2015-06-20 48 views
1

我正在從MITx在線學習python:6.00.1x。這裏的代碼Python中的混淆如果其他邏輯

x = 23.0 
epsilon = 0.01 
step = 0.1 
guess = 0.0 

while abs(guess**2-x) >= epsilon: 
    if guess <= x: 
     guess += step 
    else: 
     break 

if abs(guess**2 - x) >= epsilon: 
    print "outside" 
    print guess 
else: 
    print 'succeeded: ' + str(guess) 

根據我,while循環應該打破時,猜測值變爲23.1。因爲當猜測= 23時,如果條件,猜測< = 23,將滿足並且下一行猜測+ =步驟應該執行,這將使得猜測= 23.1,然後在下一次迭代中,猜測< = 23.0將不被滿足,並且循環將打破。但是,當我運行代碼的輸出出來是

23.0

它不應該是23.1?

+0

http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html(以及許多其他類似的鏈接,如果你谷歌) – cdarke

回答

1

您對邏輯的理解看起來很合理;這個問題實際上是以python在內部存儲(並因此添加和比較)浮點數的方式實現的。

這是你的代碼的修改版本,應該讓你看看這是怎麼回事:

x = 2 
epsilon = 0.01 
step = 0.1 
guess = 0.0 
while abs(guess**2-x) >= epsilon: 
    print format(guess, '.20'), guess <= x 
    if guess <= x: 
     guess += step 
    else: 
     break 

if abs(guess**2 - x) >= epsilon: 
    print "outside" 
    print guess 
else: 
    print 'succeeded: ' + str(guess) 

這會給你的結果:

0.0 True 
0.10000000000000000555 True 
0.2000000000000000111 True 
0.30000000000000004441 True 
0.4000000000000000222 True 
0.5 True 
0.5999999999999999778 True 
0.69999999999999995559 True 
0.79999999999999993339 True 
0.89999999999999991118 True 
0.99999999999999988898 True 
1.0999999999999998668 True 
1.1999999999999999556 True 
1.3000000000000000444 True 
1.4000000000000001332 True 
1.500000000000000222 True 
1.6000000000000003109 True 
1.7000000000000003997 True 
1.8000000000000004885 True 
1.9000000000000005773 True 
2.0000000000000004441 False 
outside 
2.0 

這裏,我們看到的guess在每個值步,顯示爲20位小數,以及python在比較時得到的值guess <= x。 因此,實際step非常非常接近(但不完全等於)數字0.1。

這裏的道德:比較浮點數時要非常小心。

2

因爲像0.1這樣的浮點數不能用float類型精確表示。所以浮點數算法也不精確。例如:

>>> 0.1 * 3 
0.30000000000000004 

在你COSE,guess達到23.0之前,你會以爲這是22.9,但它實際上是一個數量非常接近22.9,在這種情況下,可能稍微小了一點。

+0

那麼它是23.0(猜測值)> 23.0( x的值)? 也許猜測是23.0000000000000004之後所有這些增量0.1?只是說在 – Smatik

+1

@Smatik在這個例子中,'x'正好是'23.0','guess'是一個接近'22.9'或'23.0'的數字,具體取決於浮點數的詳細實現,試試google * IEEE 754 * 。 –