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.
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'
print '{0:.10f}'.format(1.0e-9)
String formatting in the documentation.
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 b
s 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
This is pretty standard print formatting, specifically for a float:
print "%.9f" % 1.0e-9
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With