Strange Python While Loop Behavior With < Comparison
Solution 1:
5 isn't necessarily 5:
t=0while t<5: #currently loop runs for 10 secondsprint"in loop",t, repr(t)
if (t<5):
print"true"
t=t+0.1
produces
inloop00trueinloop0.10.1trueinloop0.20.2trueinloop0.30.30000000000000004
[...]
inloop4.84.799999999999999trueinloop4.94.899999999999999trueinloop5.04.999999999999998true
0.1 can't be represented exactly in binary.
[Ah, I just noticed that I used 0.1 instead of 0.01, like you did. Well, it's the same issue.]
Two "how floating point works" references: classical and gentler.
Solution 2:
The value of t
on the last loop iteration is close to, but just under 5.0. It is impossible to represent 0.01 exactly in binary, so a small error creeps in each time 0.01 is added to t
. Python deems the result close enough to 5.0 to print "5.0", but it's not actually quite 5.0.
To make it work as you expect, use a Decimal
, which does not suffer from these rounding errors.
fromdecimal import Decimal
t=Decimal("0")
while t<5:
print "in loop",t
if (t<5):
print "true"
t=t+Decimal("0.01")
Solution 3:
This is because values are rounded for printing. It is absolutely what one would expect.
If you need to avoid this behaviour, then either format your output differently, or use an appropriate delta to test against, e.g. 5.0 - t < delta
delta
is any numeric value you like - it defines how close to 5 is equal to 5 for your purposes, given that in general decimal values cannot be represented exactly using a purely binary representation.
If this is unacceptable in your application, the alternative is to use a decimal class that uses a decimal representation internally.
Solution 4:
The problem is a precision error. If you change this to:
t=0while t<5: #currently loop runs for 10 secondsprint"in loop",repr(t)
if (t<5):
print"true"
t=t+0.01
you'll see that the last time through the loop t is actually something like 4.999999999999938.
Python (as well as most other programming languages) can't represent all real numbers exactly, so you end up with surprising behavior like this.
Solution 5:
Based on Marcin's recommendation of using a delta, here's a workable solution:
>>> step = 0.01
>>> t = 4.9
>>> while5.0 - t > step:
print 'in loop', t
t += stepinloop4.9inloop4.91inloop4.92inloop4.93inloop4.94inloop4.95inloop4.96inloop4.97inloop4.98inloop4.99
Post a Comment for "Strange Python While Loop Behavior With < Comparison"