The max number of significant digits in a float is 15 (the power is separate from this). So there's no point in accounting for more digits past that, as they wouldn't be right. Knowing what the power of ten for a given number will tell you how many zeros to pad out in the front.
If what you're formatting will never get above one, then the following will suffice:
from math import log10
def floatformat(f):
pwr = log10(f)
return '{:.0{}f}'.format(f, int(abs(pwr)) + 15).rstrip('0')
But if you're parsing any possible float value, you'll have to handle large numbers a bit differently to get trailing zeros and not random inaccurate digits.
def floatformat(f):
sigs = 15 # number of accurate digits that a float can contain
pwr = log10(f)
if pwr > sigs: # power above accurate digits
s = '{:.{}f}'.format(f / 10 ** int(pwr), sigs)
s = s.replace('.', '') # remove decimal point, no longer necessary here
s = s + '0' * (int(pwr) - sigs) # add in trailing zeros
elif 0 < pwr <= sigs: # power within accurate digits
s = '{:.{}f}'.format(f, sigs - int(pwr)).rstrip('0')
else: # power below accurate digits
s = '{:.0{}f}'.format(f, int(abs(pwr)) + sigs).rstrip('0')
if s[-1] == '.': s = s[:-1] # remove trailing decimal point if needed
return s
All this is doing is keeping the accurate digits, then shuffling them around to have the correct power without the scientific notation.
Examples:
>>> floatformat(0.00000008)
'0.00000008'
>>> floatformat(0.0000000000000000000000000000008)
'0.0000000000000000000000000000008'
>>> floatformat(0.00000000000000000000000000000080067)
'0.00000000000000000000000000000080067'
>>> floatformat(2.31451103e7)
'23145110.3'
>>> floatformat(2.31451103e3)
'2314.51103'
>>> 935.16087e203 == float(floatformat(935.16087e203)) # conversion check to see if power is handled correctly
True
>>> import sys
>>> floatformat(sys.float_info.max)
'179769313486231600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
>>> floatformat(sys.float_info.min)
'0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022250738585072'