2
votes

For python 3 I want to convert a float to a string, with possibly different length (i.e. number of digits) but with full precision.

Also I need to have a decimal point in any case:

1    -> '1.'
1/10 -> '0.1000000000000000055511151231257827021181583404541015625'

currently my code is this:

from decimal import Decimal
def formatMostSignificantDigits(x):
    out = str(Decimal(x))
    if out.find('.') < 0:
        out += '.'
    return out

can this be done more elegantly? (e notation would be possible, too)

2
I mean, I would use endswith instead of .find < 0, but other than that it looks fine. This would probably be better for codereview, as "more elegantly" isn't really something objective that we can give you. - Morgan Thrapp
@MorganThrapp How would endswith help with this problem? - Selcuk
@Selcuk Oh, you're right. Sorry, it's early. - Morgan Thrapp
I would have used '.' in out - Jean-François Fabre

2 Answers

2
votes

why do you use Decimal, you can just use:

x = 0.1
s = str(x)
print(s)   # this prints '0.1'

but if you use Decimal for something else than instead of this:

out = str(Decimal(x))
if out.find('.') < 0:
    out += '.'
return out

you can just use:

return Decimal(x).__str__()

Edit 1:

also good module for float precision is bigfloat:

from bigfloat import BigFloat
x = 0.1
print(BigFloat(x, precision(300)).__str__())
# thsi will print'0.10000000000000000555111512312578270211815834045410156250000000000000000000000000000000000000'
# but if you use this:
print(BigFloat(x.__str__(), precision(300)).__str__())
# it can be precise as much as you want
print(BigFloat(x.__str__(), precision(100000)).__str__()) # try this
2
votes

Use Pythons string formatting functions:

>>> x = 1.0; '{:.55f}'.format(x)
'1.0000000000000000000000000000000000000000000000000000000'
>>> x = 1/10; '{:.55f}'.format(x)
'0.1000000000000000055511151231257827021181583404541015625'

If you want to be able to feed it integers (such as 1) as well, use '{:.55f}'.format(float(x)).

If you want to strip any trailing zeroes, use '{:.55f}'.format(x).rstrip('0').

Note that 55 decimals after the point is way overkill (but it's what you showed in your question); 16 digits should suffice to express the full precision of double-precision IEEE 754 floats (20 digits for the 80-bit extended-precision you might encounter).