在我的python程序中,没有输入if语句。我已将代码简化为以下内容:
x = -5
while x < 5:
if (x == 0):
print 0
x += .01
此程序不输出任何内容。
但是,将最后一行更改为x + = .5会使程序输出0.问题是什么?
答案 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
...
哦,男孩,它实际上永远不会等于零!
解决方案:
使用整数。最可靠的。
x = -500 # times this by a 100 to make it an integer-based program
while x < 500:
if (x == 0):
print 0
x += 1
决不使用浮点运算来测试相等性,而是使用范围:
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无关。这就是计算机硬件的工作方式:)