Python 3 Float Decimal Points/Precision
Solution 1
In a word, you can't.
3.65
cannot be represented exactly as a float
. The number that you're getting is the nearest number to 3.65
that has an exact float
representation.
The difference between (older?) Python 2 and 3 is purely due to the default formatting.
I am seeing the following both in Python 2.7.3 and 3.3.0:
In [1]: 3.65
Out[1]: 3.65
In [2]: '%.20f' % 3.65
Out[2]: '3.64999999999999991118'
For an exact decimal datatype, see decimal.Decimal
.
Solution 2
The comments state the objective is to print to 2 decimal places.
There's a simple answer for Python 3:
>>> num=3.65
>>> "The number is {:.2f}".format(num)
'The number is 3.65'
or equivalently with f-strings (Python 3.6+):
>>> num = 3.65
>>> f"The number is {num:.2f}"
'The number is 3.65'
As always, the float value is an approximation:
>>> "{}".format(num)
'3.65'
>>> "{:.10f}".format(num)
'3.6500000000'
>>> "{:.20f}".format(num)
'3.64999999999999991118'
I think most use cases will want to work with floats and then only print to a specific precision.
Those that want the numbers themselves to be stored to exactly 2 decimal digits of precision, I suggest use the decimal type. More reading on floating point precision for those that are interested.
Solution 3
The simple way to do this is by using the round buit-in.
round(2.6463636263,2)
would be displayed as 2.65
.
Solution 4
Try this:
num = input("Please input your number: ")
num = float("%0.2f" % (num))
print(num)
I believe this is a lot simpler. For 1 decimal place use %0.1f
. For 2 decimal places use %0.2f
and so on.
Or, if you want to reduce it all to 2 lines:
num = float("%0.2f" % (float(input("Please input your number: "))))
print(num)
Solution 5
Try to understand through this below function using python3
def floating_decimals(f_val, dec):
prc = "{:."+str(dec)+"f}" #first cast decimal as str
print(prc) #str format output is {:.3f}
return prc.format(f_val)
print(floating_decimals(50.54187236456456564, 3))
Output is : 50.542
Hope this helps you!
darksky
C, C++, Linux, x86, Python Low latency systems Also: iOS (Objective-C, Cocoa Touch), Ruby, Ruby on Rails, Django, Flask, JavaScript, Java, Bash.
Updated on November 14, 2020Comments
-
darksky over 3 years
I am reading a text file with floating point numbers, all with either 1 or 2 decimal points. I am using
float()
to convert a line into a float, and raising aValueError
if that fails. I am storing all floats in a list. When printing it out, I'd like to print it out as a 2 decimal places floating point.Assume I have a text file with the numbers -3,65, 9,17, 1. I read each one, and once I convert them to float and append them to a list. Now in Python 2, calling
float(-3.65)
returns-3.65
. In Python 3 however,float(-3.65) returns
-3.6499999999999999` which loses its precision.I want to print the list of floats,
[-3.6499999999999999, 9.1699999999999999, 1.0]
with 2 decimal points only. Doing something along the lines of'%.1f' % round(n, 1)
would return a string. How can I return a list of all two decimal points of floats, and not strings? So far, I rounded it using[round(num, 2) for num in list]
but would need to set the decimal points / precision instead ofround()
. -
darksky over 11 yearsSo there is no way to limit the number of decimal points as an number type? To print 3.65, I would require to print it out as a string?
-
Admin over 11 years@Darksky One can only print strings. Sometimes the conversion isn't as explicit: but it is always done.
-
darksky over 11 yearsYes, so how would I represent
3.64999999999999991118
as3.65
or anything that's 2 decimal points, without it being a string? Any other type than float that I can use? -
martineau over 11 yearsUse
Decimal
in thedecimal
module instead of float point. -
Omnifarious over 11 yearsI thought Python had this change awhile ago. A change to
float
formatting so that it tried to be the shortest string that would convert back into the exactfloat
you were printing. Basically an attempt to make these kinds of rounding issues disappear most of the time. Did that change not make it into Python3? I thought I saw it in the changelog for 2.6 or 2.7. -
NPE over 11 years@Omnifarious: I've just tested, and I am seeing no difference between 2.7.3 and 3.3.0
-
Omnifarious over 11 years@NPE: I'm researching now. But my preliminary research leads me to believe that I'm remembering something about the
str
method and/or the%g
format specifier. -
Omnifarious over 11 years@NPE: Ahh, yes, it's
repr
. And it changed in Python2.7. Python3 also has it, so it's not different. docs.python.org/2.7/whatsnew/2.7.html (search for 7117) and bugs.python.org/issue7117 -
Andrew E over 6 yearsThe OP didn't need a variable to define precision - it was set at 2 places. But for variable precision, you don't need to use the arcane string addition
prc = "{:."+str(dec)+"f}"
. Instead, embed the precision:print("The number is {:.{}f}".format(f_val, dec))
. The same but with f-strings:print(f"The number is {f_val:.{dec}f}")
. -
Anekdotin over 6 yearsThis was a perfect solution for me
-
ZeerakW about 6 yearsHadn't seen the update with f-strings. Honestly not sure if I'm a fan but it's good to know!
-
Gary about 5 yearsThough be aware of the note from the documentation on
round()
thatround()
can give surprising results when given float values. The example mentioned there: "round(2.675, 2)
gives2.67
instead of the expected2.68
." -
MonsieurBeilto about 5 yearsUsing f-strings does not seem to be very readable to another user who may not be aware of the feature. On the other hand, the using "{}".format() is much more intuitive when reading.
-
cryanbhu over 3 yearsthanks for this. Tried reading the docs at docs.python.org/3/library/string.html#string-formatting , nearly died trying to find the answer and gave up