views:

1244

answers:

5

Hi all!

I am feeling difficult to convert a float to string in the following manner:

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

Seems "%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 way I know at the time is checking whether the number is int and apply "%d" instead of "%f" formatting - this is too complicated, I think. Does anyboidy know why the things above are hapenning? How to do this simpler?

Thanks.

+1  A: 

use built-in function round

Nikola Smiljanić
+1  A: 

Try something a little less than 20 digits. If you use 20 digits, it will give you the 20 digit representation of the floating point value, which might look a bit odd.

wisty
+2  A: 

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).

Alex Martelli
+4  A: 

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'
kaizer.se
+1  A: 

Using %f format specifier:

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

Using round() function:

str(round(value)).rstrip('0').rstrip('.')
Denis Otkidach