I had the same question.
Looking at the Python documentation it seems that g also supports precision values:
General format. For a given precision p >= 1, this rounds the number to p significant digits and then formats the result in either fixed-point format or in scientific notation, depending on its magnitude.
I don't know, why the other answers don't use this and I am not very experienced in Python, but it works.
This can be simply achieved by using format(0.00001, '.10g') where 10 is the precision you want.
python - Limiting floats to two decimal points - Stack Overflow
General way to print floats without the .0 part
string - How to make Python format floats with certain amount of significant digits? - Stack Overflow
Trying to format a list of floats with f-strings
Videos
I had the same question.
Looking at the Python documentation it seems that g also supports precision values:
General format. For a given precision p >= 1, this rounds the number to p significant digits and then formats the result in either fixed-point format or in scientific notation, depending on its magnitude.
I don't know, why the other answers don't use this and I am not very experienced in Python, but it works.
This can be simply achieved by using format(0.00001, '.10g') where 10 is the precision you want.
from math import log10
if log10(n) < -5:
print "%e" % n
else:
print "%f" % n
EDIT: it's also possible to put it on a single line:
("%e" if log10(n) < -5 else "%f") % n
If n might be negative, then use log10(abs(n)) in place of log10(n).
EDIT 2: Improved based on Adal's comments:
"%e" % n if n and log10(abs(n)) < -5 else ("%f" % n).rstrip("0")
This will print 0 as "0."--if you want another representation like "0" or "0.0", you'll need to special case it with a separate if.
You are running into the old problem with floating point numbers that not all numbers can be represented exactly. The command line is just showing you the full floating point form from memory.
With floating point representation, your rounded version is the same number. Since computers are binary, they store floating point numbers as an integer and then divide it by a power of two so 13.95 will be represented in a similar fashion to 125650429603636838/(2**53).
Double precision numbers have 53 bits (16 digits) of precision and regular floats have 24 bits (8 digits) of precision. The floating point type in Python uses double precision to store the values.
For example,
>>> 125650429603636838/(2**53)
13.949999999999999
>>> 234042163/(2**24)
13.949999988079071
>>> a = 13.946
>>> print(a)
13.946
>>> print("%.2f" % a)
13.95
>>> round(a,2)
13.949999999999999
>>> print("%.2f" % round(a, 2))
13.95
>>> print("{:.2f}".format(a))
13.95
>>> print("{:.2f}".format(round(a, 2)))
13.95
>>> print("{:.15f}".format(round(a, 2)))
13.949999999999999
If you are after only two decimal places (to display a currency value, for example), then you have a couple of better choices:
- Use integers and store values in cents, not dollars and then divide by 100 to convert to dollars.
- Or use a fixed point number like decimal.
There are new format specifications, String Format Specification Mini-Language:
You can do the same as:
"{:.2f}".format(13.949999999999999)
Note 1: the above returns a string. In order to get as float, simply wrap with float(...):
float("{:.2f}".format(13.949999999999999))
Note 2: wrapping with float() doesn't change anything:
>>> x = 13.949999999999999999
>>> x
13.95
>>> g = float("{:.2f}".format(x))
>>> g
13.95
>>> x == g
True
>>> h = round(x, 2)
>>> h
13.95
>>> x == h
True
You'll want the g modifier for format that drops insignificant zeroes;
>>> "{0:.6g}".format(5.5657188485)
'5.56572'
>>> "{0:.6g}".format(3.539)
'3.539'
Sorry, my update also includes the fact that I am restricted to using Python 2.4.3, which does not have format() function.
The format specifiers work even without the .format() function:
>>> for i in a:
... print '%.6g' % (i,)
...
1.01885e+10
5.56572
3.539
22.1523
0
15.9638
0.284024
7.58097
24.3469
There is a way to retain trailing zeros so that it consistently shows the number of significant digits. Not exactly what OP wanted, but probably useful to many.
a = [10188469102.605597,5.5657188485,3.539,22.1522612479,0,15.9638450858,0.284024,7.58096703786,24.3469152383]
for i in a:
print("{:#.6g}".format(i))
Output
1.01885e+10
5.56572
3.53900
22.1523
0.00000
15.9638
0.284024
7.58097
24.3469
Note that this will only work with the format function and not with % operator.
According to the docs:
The
'#'option causes the “alternate form” to be used for the conversion. The alternate form is defined differently for different types. This option is only valid for integer, float, complex and Decimal types.
'g': General format ... insignificant trailing zeros are removed from the significand, and the decimal point is also removed if there are no remaining digits following it, unless the '#' option is used.