Converting a float to a string without rounding it

PythonStringFloating PointRounding

Python Problem Overview


I'm making a program that, for reasons not needed to be explained, requires a float to be converted into a string to be counted with len(). However, str(float(x)) results in x being rounded when converted to a string, which throws the entire thing off. Does anyone know of a fix for it? Here's the code being used if you want to know:

len(str(float(x)/3))

Python Solutions


Solution 1 - Python

Some form of rounding is often unavoidable when dealing with floating point numbers. This is because numbers that you can express exactly in base 10 cannot always be expressed exactly in base 2 (which your computer uses).

For example:

>>> .1
0.10000000000000001

In this case, you're seeing .1 converted to a string using repr:

>>> repr(.1)
'0.10000000000000001'

I believe python chops off the last few digits when you use str() in order to work around this problem, but it's a partial workaround that doesn't substitute for understanding what's going on.

>>> str(.1)
'0.1'

I'm not sure exactly what problems "rounding" is causing you. Perhaps you would do better with string formatting as a way to more precisely control your output?

e.g.

>>> '%.5f' % .1
'0.10000'
>>> '%.5f' % .12345678
'0.12346'

Documentation here.

Solution 2 - Python

len(repr(float(x)/3))

However I must say that this isn't as reliable as you think.

Floats are entered/displayed as decimal numbers, but your computer (in fact, your standard C library) stores them as binary. You get some side effects from this transition:

>>> print len(repr(0.1))
19
>>> print repr(0.1)
0.10000000000000001

The explanation on why this happens is in this chapter of the python tutorial.

A solution would be to use a type that specifically tracks decimal numbers, like python's decimal.Decimal:

>>> print len(str(decimal.Decimal('0.1')))
3

Solution 3 - Python

Other answers already pointed out that the representation of floating numbers is a thorny issue, to say the least.

Since you don't give enough context in your question, I cannot know if the decimal module can be useful for your needs:

http://docs.python.org/library/decimal.html

Among other things you can explicitly specify the precision that you wish to obtain (from the docs):

>>> getcontext().prec = 6
>>> Decimal('3.0')
Decimal('3.0')
>>> Decimal('3.1415926535')
Decimal('3.1415926535')
>>> Decimal('3.1415926535') + Decimal('2.7182818285')
Decimal('5.85987')
>>> getcontext().rounding = ROUND_UP
>>> Decimal('3.1415926535') + Decimal('2.7182818285')
Decimal('5.85988')

A simple example from my prompt (python 2.6):

>>> import decimal
>>> a = decimal.Decimal('10.000000001')
>>> a
Decimal('10.000000001')
>>> print a
10.000000001
>>> b = decimal.Decimal('10.00000000000000000000000000900000002')
>>> print b
10.00000000000000000000000000900000002
>>> print str(b)
10.00000000000000000000000000900000002
>>> len(str(b/decimal.Decimal('3.0')))
29

Maybe this can help? decimal is in python stdlib since 2.4, with additions in python 2.6.

Hope this helps, Francesco

Solution 4 - Python

I know this is too late but for those who are coming here for the first time, I'd like to post a solution. I have a float value index and a string imgfile and I had the same problem as you. This is how I fixed the issue

index = 1.0
imgfile = 'data/2.jpg'
out = '%.1f,%s' % (index,imgfile)
print out

The output is

1.0,data/2.jpg

You may modify this formatting example as per your convenience.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGalileoView Question on Stackoverflow
Solution 1 - PythonJohn FouhyView Answer on Stackoverflow
Solution 2 - PythonnoskloView Answer on Stackoverflow
Solution 3 - PythonFrancescoView Answer on Stackoverflow
Solution 4 - PythonHarsh WardhanView Answer on Stackoverflow