为什么这个While循环终止?

时间:2013-04-14 02:57:39

标签: python python-2.7

x=1.0
i=1
while(1.0+x>1.0):
    x=x/2
    i=i+1
print i

跟进问题,为什么i = 54的值?

我的想法是循环不会结束,因为(1.0 + x)的值将始终保持大于1.0。但是在运行代码时,情况并非如此。

4 个答案:

答案 0 :(得分:6)

由于inaccuracy of floating pointx的值总是很小,以至于Python无法存储其值,它实际上变为0。它需要54次迭代(53, actually)才能进入该阶段,这就是i为54的原因。

例如,

>>> 1e-1000
0.0

答案 1 :(得分:6)

为什么54? - 实际上它是53,因为它是在你递增之前

>>> 2.**-54
5.551115123125783e-17

>>> 2.**-53
1.1102230246251565e-16

>>> 2.**-52
2.220446049250313e-16

>>> sys.float_info.epsilon
2.220446049250313e-16

如果你将一些小到的东西加到1,它仍然是1。

答案 2 :(得分:0)

当处理浮点数或浮点数时,你会遇到臭名昭着的Floating Point Epsilon

在您的情况下,这需要54次迭代才能达到该阈值以下(因为Python中的默认浮点类型是单精度,而单精度的浮点epsilon是:

def machineEpsilon(func=float):
    machine_epsilon = func(1)
    while func(1)+func(machine_epsilon) != func(1):
        machine_epsilon_last = machine_epsilon
        machine_epsilon = func(machine_epsilon) / func(2)
    return machine_epsilon_last

因此:

In [2]: machineEpsilon(float)
Out[2]: 2.2204460492503131e-16

53次迭代来自哪里?

从代码中的这一行开始:

x=x/2

x的当前值分配给x/2,这意味着在第53次迭代中,它变为:

1.11022302463e-16

哪个小于浮点epsilon。

答案 3 :(得分:0)

正如已经指出的那样 - 这是因为float的准确性。如果你想克服这个“限制”,你可以使用Python的fractions模块,例如:

from fractions import Fraction as F

x = F(1, 1)
i=1
while(F(1, 1)+x>1.0):
    print i, x
    x = F(1, x.denominator * 2)
    i=i+1
print i

(注意:这将持续到中断)