Program not entering if statement

2020-04-09 19:25发布

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):
        print 0
    x += .01

This program does not output anything.

However, changing the last line to x += .5 makes the program output 0. What's the problem?

7条回答
Animai°情兽
2楼-- · 2020-04-09 19:32
-0.01
7.52869988574e-16
0.01

I suggest you say x > -.001 and x < .001 or something of the sort

查看更多
Emotional °昔
3楼-- · 2020-04-09 19:34

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) ...
查看更多
男人必须洒脱
4楼-- · 2020-04-09 19:36

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.

查看更多
我只想做你的唯一
5楼-- · 2020-04-09 19:39

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.

查看更多
放我归山
6楼-- · 2020-04-09 19:43

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:

  1. 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
    
  2. 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
    
查看更多
【Aperson】
7楼-- · 2020-04-09 19:47

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.

查看更多
登录 后发表回答