簡體   English   中英

為什么此While循環終止?

[英]Why does this While loop terminate?

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。 但是,在運行代碼時並非如此。

由於浮點數不精確性,總是會出現x的值如此之小以至於Python無法存儲其值,並且它實際上變為0 到該階段需要54次迭代( 實際上是53次),這就是為什么i是54。

例如,

>>> 1e-1000
0.0

為什么是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。

在處理浮點數或浮點數時,會遇到臭名昭著的浮點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。

正如已經指出的-這是因為float s的准確性。 如果您想克服這種“局限性”,可以使用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

(注意:這將持續到被中斷為止)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM