程序不输入if语句

时间:2011-09-28 16:10:34

标签: python floating-point

在我的python程序中,没有输入if语句。我已将代码简化为以下内容:

x = -5
while x < 5:
    if (x == 0):
        print 0
    x += .01

此程序不输出任何内容。

但是,将最后一行更改为x + = .5会使程序输出0.问题是什么?

7 个答案:

答案 0 :(得分:9)

浮点数表示可能不够准确。你永远不应该测试零平等,而是使用

if (abs(x) < 1E-10) ...

答案 1 :(得分:7)

看到印刷声明的力量......

让我们插入一份印刷声明......

x = -5
while x < 5:
    if (x == 0):
        print 0
    x += .01
    print x

运行此程序,并检查0左右的输出显示问题:

...
-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
...

哦,男孩,它实际上永远不会等于零!

解决方案:

  1. 使用整数。最可靠的。

    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. 决不使用浮点运算来测试相等性,而是使用范围:

    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
    

答案 2 :(得分:3)

这是一个舍入问题 - 十进制值无法用二进制表示,因此x永远不会完全等于0.0000000000 ....

尝试用if (x == 0):

替换if -0.001 < x < 0.001:

顺便说一下,在python if语句中不需要括号。

修改: 以0.01为步长打印出介于-1和1之间的值表明情况就是这样 - 其中零应为打印7.52869988574e-16。

答案 3 :(得分:3)

其他人已指出浮点数无法准确表示值的问题。如果您需要完全数字的十进制表示,您可以使用Decimal类:

from decimal import Decimal

x = Decimal(-5)
while x < 5:
    if (x == 0):
        print 0
    x += Decimal(".01")

这将按预期打印0

请注意使用字符串作为增量。如果您使用Decimal(.01),那么精确表示0.01会有同样的问题,因为您从浮点数转换并且已经失去了准确性,因此该类不允许这样做。

答案 4 :(得分:0)

在二进制文件中,.01没有确切的表示,但.5确实如此。

如果你将1/3表示为.333333,并且在你达到1之前一直加1/3,这就是你在十进制中遇到的同样的问题。经过三次加法,你得到的.999999不完全等于1

Don't compare non-integers for equality除非您准确理解这样做的规则,并且100%确定您的案例是可行的案例之一。

答案 5 :(得分:0)

-0.01
7.52869988574e-16
0.01

我建议你说x&gt; -.001和x&lt; .001或类似的东西

答案 6 :(得分:0)

为了精确地对您的查询,浮点数以二进制(基数2)分数存储在计算机硬件中。因此,即使您在变量中存储了0.01之类的浮点数,计算机也会最终将其转换为等效的二进制值。为方便起见,将0.01 float转换为二进制:

0.01 * 2 = 0.02 [0]
0.02 * 2 = 0.04 [0] 
0.04 * 2 = 0.08 [0]
0.08 * 2 = 0.16 [0]
0.16 * 2 = 0.32 [0]
0.32 * 2 = 0.64 [0]
0.64 * 2 = 1.28 [0]
0.28 * 2 = 0.56 [0]
0.56 * 2 = 1.12 [1]
...

这个计算过于冗长,无法完整显示,可能根本不会结束。但我想在此声明的事实是,大多数小数位数不能精确地转换为二进制小数。因此,您存储的小数点将由存储在机器中的二进制浮动分数近似(显然不能存储非常长的二进制值)。因此,当使用该值进行计算时,您当然不应期望准确的浮动值。在您的代码中放置x + = 0.01就是这种情况。 然而,将0.5转换为二进制等效值将得到:

0.5 * 2 = 1.0 [1]

所以二进制当量0.5浮点数为0.1 。因为它在您的机器中完美地以二进制表示。你会得到确切的结果。

它与您的代码或python无关。这就是计算机硬件的工作方式:)