In my python program, an if statement is not being entered. I have simplified the code to the following:
x = -5
while x < 5:
if (x == 0):
prin
This is a rounding issue - decimal values cannot be represented exactly in binary, so x never exactly equals 0.0000000000....
try replacing if (x == 0):
with if -0.001 < x < 0.001:
BTW, the parentheses are unnecessary in a python if
statement.
edit: Printing out the values between -1 and 1 in steps of 0.01 shows this is the case - where zero should be it prints 7.52869988574e-16.
Behold the power of the print statement...
Let us insert a print statement...
x = -5
while x < 5:
if (x == 0):
print 0
x += .01
print x
Running this program, and inspecting the output around 0 reveals the problem:
...
-0.13
-0.12
-0.11
-0.1
-0.0900000000001
-0.0800000000001
-0.0700000000001
-0.0600000000001
-0.0500000000001
-0.0400000000001
-0.0300000000001
-0.0200000000001
-0.0100000000001
-6.23077978101e-14
0.00999999999994
0.0199999999999
0.0299999999999
0.0399999999999
0.0499999999999
0.0599999999999
0.0699999999999
0.0799999999999
0.0899999999999
0.0999999999999
0.11
0.12
0.13
...
Oh boy, it is never actually equal to zero!
Solutions:
Use integers. Most reliable.
x = -500 # times this by a 100 to make it an integer-based program
while x < 500:
if (x == 0):
print 0
x += 1
Never test equality with floating point arithmetic, but rather use a range:
delta = 0.00001 #how close do you need to get
point = 0 #point we are interested in
if (point-delta) <= x <= (point+delta):
# do stuff
In binary, .01 has no exact representation but .5 does.
It's the same problem you'd have in decimal if you represented 1/3 as .333333 and kept adding 1/3 until you reached 1. After three additions, you'd have .999999 which is not exactly equal to 1.
Don't compare non-integers for equality unless you precisely understand the rules for doing so and are 100% sure your case is one of the ones that will work.
Floating point number representation might not be accurate enough. You should never test for zero equality but instead use something along
if (abs(x) < 1E-10) ...
Others have pointed out the issue with floating-point numbers being unable to represent values exactly. If you need exact decimal representation of a number, you can use the Decimal
class:
from decimal import Decimal
x = Decimal(-5)
while x < 5:
if (x == 0):
print 0
x += Decimal(".01")
This will print 0
as you expect.
Note the use of a string for the increment. If you used Decimal(.01)
you'd have the same problem with accurate representation of 0.01, because you're converting from a floating-point number and have already lost the accuracy, so the class doesn't allow that.
-0.01
7.52869988574e-16
0.01
I suggest you say x > -.001 and x < .001 or something of the sort