2016-03-09 18 views
4

我是一個新的Python和我發現了一個令人困惑的結果在我的Mac使用Python3.5.1的時候,我只是在我的終端運行此命令爲什麼1 // 0.05導致19.0在python中?

1 // 0.05 

然而,我的屏幕上印刷19.0。從我的角度來看,它應該是20.有人能解釋這裏發生了什麼嗎?我已經知道'//'與math.floor()函數類似。但我仍然無法理解這一點。

+2

它分開然後向下舍入。這就是它。 – MarkyPython

+3

@MarkyPython:除此之外還有更多。在我的機器上,'1/0.05'是'20.0',但'1 // 0.05'是'19.0'。 – dan04

+5

長話短說:在處理浮點數時,不要期望*任何特定的結果。 – deceze

回答

6

因爲Python浮點文字0.05表示比數學值0.05略大的數字。

>>> '%.60f' % 0.05 
'0.050000000000000002775557561562891351059079170227050781250000' 

//是地板分裂,這意味着結果是最大的整數n使得n倍除數爲小於或等於所述被除數。自20倍0.05000000000000000277555756156289135105907917022705078125大於1,這意味着正確的結果爲19。

至於爲什麼 Python的字面0.05不代表數0.05,以及約浮點許多其他的事情,請參閱What Every Computer Scientist Should Know About Floating-Point Arithmetic

+0

此外,它在這種情況下不會返回* integer *,但會浮動。 –

+1

@AnttiHaapala:我確實懷疑我是否會逃避那個術語。它返回一個表示整數的浮點值。它不返回的是Python類型'int'(或'long'),但我在這裏使用「integer」這個詞來表示整數的數學概念,而不是稱爲「int」的Python類型。 –

+0

@SteveJessop感謝您的幫助,我真的應該在編程中注意浮點值。 –

3

0.05在浮點上不能完全表示。 "%0.20f" % 0.05表明,0.05被存儲爲比所述精確值的值非常稍大:

>>> print "%0.20f" % 0.05 
0.05000000000000000278 

在另一方面1/0.05確實出現了整整20:

>>> print "%0.20f" % (1/0.05) 
20.00000000000000000000 

然而所有浮點值被四捨五入在存儲時加倍,但計算精度更高。在這種情況下,由1//0.05執行的發言操作似乎完全以內部精度完成,因此向下舍入。

1

正如前面的回答者已經正確指出的那樣,0.05 = 1/20的分數不能用有限數量的基數 - 二位數來精確表示。它適用於重複分數0.0000 1100 1100 1100 ...(很像1/3 = 0.333 ......在熟悉的base-10中)。

但是,這不是一個相當完整的回答你的問題,因爲有怪事會在這裏的另一位:

>>> 1/0.05 
20.0 
>>> 1 // 0.05 
19.0 

使用「真師」運營商/發生,得到所需要的答案20.0。你在這裏很幸運:分部的舍入誤差完全消除了表示值0.05本身的錯誤。

但是如何來1 // 0.05返回19?是不是a // b應該和math.floor(a /b)一樣?爲什麼///之間的不一致?

注意,divmod功能與//操作是一致的:

>>> divmod(1, 0.05) 
(19.0, 0.04999999999999995) 

這種行爲可以通過執行計算與精確合理的算術浮點除法來解釋。當您使用Python(在符合IEEE 754的平臺上)編寫文字0.05時,實際值爲3602879701896397/72057594037927936 = 0.05000000000000000277555756156289135105907917022705078125。這個值恰好是更多比預期的0.05,這意味着它的倒數將略爲減去

準確地說,3602879701896397分之72057594037927936= 19.999999999999998889776975374843521206126552300723564152465244707437044687 ...

所以,//divmod看到的19.一種整數商其餘工程以0.04999999999999994726440633030506432987749576568603515625,它是圓形的以顯示爲0.04999999999999995。所以,上面的divmod答案實際上對53位精度很好,因爲原始錯誤值爲0.05

但是/呢?那麼,真實商72057594037927936/3602879701896397不能表示爲float,所以它必須四捨五入,或者降至20-2**-48(誤差約爲2.44e-15)或者最高爲20.0(誤差約爲1.11e-15) 。 Python正確選擇更準確的選擇,20.0

所以,似乎Python的浮點除法內部具有足夠高的精度做知道1/0.05(這是float字面0.05,沒有確切的小數0.05),實際上是比20,但float類型本身不能代表差異。

在這一點上你可能會想:「那又怎麼樣?我不在乎Python是否給出了錯誤值的正確倒數。我想知道如何在第一時間得到正確的值「而這個問題的答案可以是:(!不要忘記引號)

相關問題