10

So this works fine:

>>> float(1.0e-1)
0.10000000000000001

But when dealing with a larger number, it won't print:

>>> float(1.0e-9)
1.0000000000000001e-09

Is there a way to force this? Maybe using numpy or something.

joedborg
  • 16,427
  • 30
  • 80
  • 114

6 Answers6

17
print '{0:.10f}'.format(1.0e-9)

String formatting in the documentation.

Cat Plus Plus
  • 119,938
  • 26
  • 191
  • 218
  • Doesn't work before Python 2.6 (which is not a big deal, but you should have mentioned it). More seriously, this fixes the number of digits after the decimal point, which is probably not what the OP wants. – zwol Dec 01 '11 at 17:48
11

Everyone suggesting the use of the f string format code is implicitly assuming that it's okay to fix the number of digits after the decimal point. That seems like a very shaky assumption to me. However, if you don't make that assumption, there is no built-in mechanism to do what you want. This is the best hack I came up with when faced with a similar problem (in a PDF generator -- numbers in PDF can't use exponential notation). You probably want to take all the bs off the strings, and there may be other Python3-isms in here.

_ftod_r = re.compile(
    br'^(-?)([0-9]*)(?:\.([0-9]*))?(?:[eE]([+-][0-9]+))?$')
def ftod(f):
    """Print a floating-point number in the format expected by PDF:
    as short as possible, no exponential notation."""
    s = bytes(str(f), 'ascii')
    m = _ftod_r.match(s)
    if not m:
        raise RuntimeError("unexpected floating point number format: {!a}"
                           .format(s))
    sign = m.group(1)
    intpart = m.group(2)
    fractpart = m.group(3)
    exponent = m.group(4)
    if ((intpart is None or intpart == b'') and
        (fractpart is None or fractpart == b'')):
        raise RuntimeError("unexpected floating point number format: {!a}"
                           .format(s))

    # strip leading and trailing zeros
    if intpart is None: intpart = b''
    else: intpart = intpart.lstrip(b'0')
    if fractpart is None: fractpart = b''
    else: fractpart = fractpart.rstrip(b'0')

    if intpart == b'' and fractpart == b'':
        # zero or negative zero; negative zero is not useful in PDF
        # we can ignore the exponent in this case
        return b'0'

    # convert exponent to a decimal point shift
    elif exponent is not None:
        exponent = int(exponent)
        exponent += len(intpart)
        digits = intpart + fractpart
        if exponent <= 0:
            return sign + b'.' + b'0'*(-exponent) + digits
        elif exponent >= len(digits):
            return sign + digits + b'0'*(exponent - len(digits))
        else:
            return sign + digits[:exponent] + b'.' + digits[exponent:]

    # no exponent, just reassemble the number
    elif fractpart == b'':
        return sign + intpart # no need for trailing dot
    else:
        return sign + intpart + b'.' + fractpart
zwol
  • 129,170
  • 35
  • 235
  • 347
3

Here's zwol's answer simplified and converted to standard python format:

import re
def format_float_in_standard_form(f):
    s = str(f)
    m = re.fullmatch(r'(-?)(\d)(?:\.(\d+))?e([+-]\d+)', s)
    if not m:
        return s
    sign, intpart, fractpart, exponent = m.groups('')
    exponent = int(exponent) + 1
    digits = intpart + fractpart
    if exponent < 0:
        return sign + '0.' + '0'*(-exponent) + digits
    exponent -= len(digits)
    return sign + digits + '0'*exponent + '.0'
panda-34
  • 3,837
  • 17
  • 24
3

This is pretty standard print formatting, specifically for a float:

print "%.9f" % 1.0e-9
cosmosis
  • 5,647
  • 3
  • 30
  • 28
1
>>> a
1.0000000000000001e-09
>>> print "heres is a small number %1.9f" %a
heres is a small number 0.000000001
>>> print "heres is a small number %1.13f" %a
heres is a small number 0.0000000010000
>>> b
11232310000000.0
>>> print "heres is a big number %1.9f" %b
heres is a big number 11232310000000.000000000
>>> print "heres is a big number %1.1f" %b
heres is a big number 11232310000000.0
oz123
  • 25,576
  • 25
  • 124
  • 179
0

Use %e when printing your number:

>>> a = 0.1234567
>>> print 'My number is %.7e'%a
My number 1.2345670e-01

If you use %g it will automatically choose the best visualization for you:

>>> print 'My number is %.7g'%a
My number is 0.1234567
toti08
  • 2,342
  • 5
  • 22
  • 34