Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert float to string with cutting zero decimals afer point in Python

I am having difficulty converting a float to string in the following manner:

20.02  --> 20.02
20.016 --> 20.02
20.0   --> 20

It seems that%g format is the best for that, but I am getting strange results:

In [30]: "%.2g" % 20.03
Out[30]: '20'

In [31]: "%.2g" % 20.1
Out[31]: '20'

In [32]: "%.2g" % 20.3
Out[32]: '20'

In [33]: "%.2g" % 1.2
Out[33]: '1.2'

In [34]: "%.2g" % 1.0
Out[34]: '1'

In [35]: "%.2g" % 2.0
Out[35]: '2'

In [36]: "%.2g" % 2.2
Out[36]: '2.2'

In [37]: "%.2g" % 2.25
Out[37]: '2.2'

In [38]: "%.2g" % 2.26
Out[38]: '2.3'

In [39]: "%.3g" % 2.26
Out[39]: '2.26'

In [40]: "%.3g" % 2.25
Out[40]: '2.25'

In [41]: "%.3g" % 20.02
Out[41]: '20'

In [42]: "%.3g" % 20.016
Out[42]: '20'

In [43]: "%.20g" % 20.016
Out[43]: '20.015999999999998238'

The only solution I know at the moment is checking whether the number is an int and applying %d instead of %f formatting - this is too complicated, I think.

Does anybody know why the things above are hapenning? How to do this in a simpler way?

Thanks.

like image 536
Serge Tarkovski Avatar asked Nov 16 '09 15:11

Serge Tarkovski


3 Answers

Using %f format specifier:

('%.2f' % (value,)).rstrip('0').rstrip('.')

Using round() function:

str(round(value)).rstrip('0').rstrip('.')
like image 97
Denis Otkidach Avatar answered Oct 25 '22 12:10

Denis Otkidach


I'm not sure what exactly you are finding complicated here -- you're getting exactly the results specified e.g. here. E.g.:

In [32]: "%.2g" % 20.3
Out[32]: '20'

In [33]: "%.2g" % 1.2
Out[33]: '1.2'

In each case, you have requested that 2 digits be shown in all, and that's what is happening (both digits come before the trailing dot in one case, one before and one after in the other case, but that's an obvious consequence of the numbers' respective magnitudes).

When you ask for 20 digits, you're shown 20 digits -- most aren't meaningful of course (a double-precision IEEE floating point is good for only about 16 digits of precision), so it's more sensible to ask for fewer. You do know of course that floats are represented in binary, as explained here, right? Use decimal (much slower, of course, since what your computer's hardware supplies is binary floating point, the decimal version must all be synthesized in software) is what you need are decimal-represented floats (e.g., for monetary computations).

like image 40
Alex Martelli Avatar answered Oct 25 '22 13:10

Alex Martelli


Use round together with %g -- you want at most 2 digits shown, so round to two digits, then use %g to print it as short as possible:

>>> "%g" % round(20.016, 2)
'20.02'
>>> "%g" % round(20, 2)
'20'
like image 42
u0b34a0f6ae Avatar answered Oct 25 '22 12:10

u0b34a0f6ae