我今年夏天在网上从MITx学习python:6.00.1x。这是代码
x = 23.0
epsilon = 0.01
step = 0.1
guess = 0.0
while abs(guess**2-x) >= epsilon:
if guess <= x:
guess += step
else:
break
if abs(guess**2 - x) >= epsilon:
print "outside"
print guess
else:
print 'succeeded: ' + str(guess)
根据我的说法,当guess的值变为23.1时,while循环应该会中断。因为当guess = 23时,if条件,猜测&lt; = 23,将满足并且下一行猜测+ =步骤应该执行,这将使guess = 23.1然后在下一次迭代中,猜测&lt; = 23.0将不会满足并且循环会打破。但是当我运行代码时输出结果是
外
23.0
不应该是23.1吗?
答案 0 :(得分:2)
因为0.1
之类的浮点数无法使用float
类型精确表示。因此浮点数运算也不精确。例如:
>>> 0.1 * 3
0.30000000000000004
在您的cose中,在guess
到达23.0
之前,您会认为它是22.9
,但它实际上是一个非常接近22.9
的数字,在这种情况,可能要小一点。
答案 1 :(得分:1)
这里对逻辑的理解似乎很合理;问题实际上是python在内部存储(并因此添加和比较)浮点数的方式。
以下是您的代码的修改版本,可让您了解正在发生的事情:
x = 2
epsilon = 0.01
step = 0.1
guess = 0.0
while abs(guess**2-x) >= epsilon:
print format(guess, '.20'), guess <= x
if guess <= x:
guess += step
else:
break
if abs(guess**2 - x) >= epsilon:
print "outside"
print guess
else:
print 'succeeded: ' + str(guess)
这会给你结果:
0.0 True
0.10000000000000000555 True
0.2000000000000000111 True
0.30000000000000004441 True
0.4000000000000000222 True
0.5 True
0.5999999999999999778 True
0.69999999999999995559 True
0.79999999999999993339 True
0.89999999999999991118 True
0.99999999999999988898 True
1.0999999999999998668 True
1.1999999999999999556 True
1.3000000000000000444 True
1.4000000000000001332 True
1.500000000000000222 True
1.6000000000000003109 True
1.7000000000000003997 True
1.8000000000000004885 True
1.9000000000000005773 True
2.0000000000000004441 False
outside
2.0
在这里,我们看到每一步guess
的值,显示为20位小数,以及python在进行比较guess <= x
时得到的值。
因此step
的实际值非常非常接近(但不完全等于)数字0.1。
这里的道德:在比较浮点数时要非常小心。