为什么我的程序在执行看似无限循环时会停止?
Why is my program stopping when doing a seemingly infinite loop?
这一定很明显,但我目前正在做一个以这段代码片段为特色的小教程:
n=0
a=1
while a>0:
n=n+1
a=(1.0+2.0**(-n))-1.0
print (n)
我已经尝试 运行 它,但它一直卡在 n=53。为什么?我只是假设 while
永远是真的...
如果将最后一行更改为 print(n, a)
,您可以更清楚地看到发生了什么:
n = 0
a = 1
while a > 0:
n = n + 1
a = (1.0 + 2.0 ** (-n)) - 1.0
print(n, a)
输出:
1 0.5
2 0.25
3 0.125
4 0.0625
# ...
50 8.881784197001252e-16
51 4.440892098500626e-16
52 2.220446049250313e-16
53 0.0
如您所见,a
每次循环都是大小的一半。最终,2.0 ** (-n)
太小以至于浮点数学(精度有限)无法区分 1.0
和 1.0 + 2.0 ** (-n)
:
>>> 1.0 + 2.0 ** -51
1.0000000000000004
>>> 1.0 + 2.0 ** -52
1.0000000000000002
>>> 1.0 + 2.0 ** -53
1.0
…当这种情况发生时,从 1.0
中减去 1.0
得到 0.0
,并且 while
循环终止。
这一定很明显,但我目前正在做一个以这段代码片段为特色的小教程:
n=0
a=1
while a>0:
n=n+1
a=(1.0+2.0**(-n))-1.0
print (n)
我已经尝试 运行 它,但它一直卡在 n=53。为什么?我只是假设 while
永远是真的...
如果将最后一行更改为 print(n, a)
,您可以更清楚地看到发生了什么:
n = 0
a = 1
while a > 0:
n = n + 1
a = (1.0 + 2.0 ** (-n)) - 1.0
print(n, a)
输出:
1 0.5
2 0.25
3 0.125
4 0.0625
# ...
50 8.881784197001252e-16
51 4.440892098500626e-16
52 2.220446049250313e-16
53 0.0
如您所见,a
每次循环都是大小的一半。最终,2.0 ** (-n)
太小以至于浮点数学(精度有限)无法区分 1.0
和 1.0 + 2.0 ** (-n)
:
>>> 1.0 + 2.0 ** -51
1.0000000000000004
>>> 1.0 + 2.0 ** -52
1.0000000000000002
>>> 1.0 + 2.0 ** -53
1.0
…当这种情况发生时,从 1.0
中减去 1.0
得到 0.0
,并且 while
循环终止。