I am new to python and I was writing something like:
t = 0.
while t<4.9:
t = t + 0.1
if t == 1.:
... do something ...
I noticed that the if statement was never being executed. So I modified the code to look like this:
''' Case a'''
t = 0.
while t<4.9:
t = t + 0.1
print(t)
print(t == 5.)
When I run this I get:
>>> ================================ RESTART ================================
>>>
5.0
False
This was a surprise because I expected the comparison to test as True. Then, I tried the following two cases:
''' Case b'''
t = 0
while t<5:
t = t + 1
print(t)
print(t == 5)
''' Case c'''
t = 0.
while t<5:
t = t + 0.5
print(t)
print(t == 5)
When I run the last 2 cases (b and c) the comparison in the final statement tests as True. I do not understand why it is so or why it seems that the behavior is not consistent. What am I doing wrong?
The problem is that binary floating point arithmetic is not precise so you will get small errors in the calculations. In particular the number 0.1 has no exact binary representation. When you calculate using floating point numbers the very small errors cause the result to be slightly incorrect from what you might expect and that makes the equality test fail.
This small error might not be visible when printing the float with the default string representation. Try using repr
instead, as this gives a slightly more accurate representation of the number (but still not 100% accurate):
>>> print(repr(t))
4.999999999999998
>>> print(t == 5.)
False
To get an accurate string representation of a float you can use the format
method:
>>> print '{0:.60f}'.format(t)
4.999999999999998223643160599749535322189331054687500000000000
>>> print '{0:.60f}'.format(0.1)
0.100000000000000005551115123125782702118158340454101562500000
A general rule with floating point arithmetic is to never make equality comparisons.
The reason why it works when you used 0.5 is because 0.5 does have an exact representation as a binary floating point number so you don't see any problem in that case. Similarly it would work for 0.25 or 0.125.
If you need precise calculations you can use a decimal type instead.
from decimal import Decimal
step = Decimal('0.1')
t = Decimal(0)
while t < Decimal(5):
t += step
print(t)
print(t == Decimal(5))
Result:
5.0 True
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With