1
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

4 回答 4

6

由于浮点数的不准确,总会有这样的时候, 的值x太小,Python 无法存储它的值,本质上变成了0. 到达那个阶段需要 54 次迭代(实际上是 53i次),这就是为什么是 54 次。

例如,

>>> 1e-1000
0.0
于 2013-04-14T02:59:45.703 回答
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。

于 2013-04-14T03:01:42.903 回答
1

在处理浮点数或浮点数时,您会遇到臭名昭著的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

它将当前值分配xx/2意味着在第 53 次迭代中,它变成了:

1.11022302463e-16

这小于浮点 epsilon。

于 2013-04-14T03:08:58.833 回答
0

正如已经指出的那样 - 这是因为floats 的准确性。如果你想克服这个“限制”,你可以使用 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

(注意:这将一直持续到被打断)

于 2013-04-14T03:11:10.483 回答