2013-04-14 179 views
1
x=1.0 
i=1 
while(1.0+x>1.0): 
    x=x/2 
    i=i+1 
print i 

後續問題,爲什麼是i = 54的值?爲什麼While循環終止?

我的想法是,循環不會結束,因爲(1.0 + x)的值將始終保持大於1.0。但是在運行代碼時,情況並非如此。

+0

因爲float精度 – JBernardo

回答

6

由於inaccuracy of floating point,總會出現x的值太小而導致Python無法存儲其值的情況,實際上它會變成0。這需要54次迭代(53, actually)去那個階段,這就是爲什麼i是54

例如,

>>> 1e-1000 
0.0 
+0

其實一到浮點數(雙精度)接近於零,它需要比53'2更多的步驟。** - 1074'對'2。** - 1075'。這裏的關鍵是添加1 – JBernardo

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

0

當花車處理或浮點數,你會遇到臭名昭著Floating Point Epsilon

在你的情況,這需要54次迭代得到低於閾值(因爲在Python默認浮點類型是單精度,併爲單精度浮點小量是:

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。

0

正如已經指出的那樣 - 這是因爲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 

(注:這將繼續下去,直到打斷)