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。但是在运行代码时,情况并非如此。
答案 0 :(得分:6)
由于inaccuracy of floating point,x
的值总是很小,以至于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
(注意:这将持续到中断)