我嘗試在Python這個簡單的數學運算Python的數學精度
>>> math.floor(8.2-0.21)
7.0
>>> math.floor(8.21-0.2)
8.0
>>> math.floor(8.2-0.2)
7.0
第三個應該返回8,但它是返回7?
UPDATE
我已經嘗試在PHP,Ruby和JAVA,我已經得到了相同的結果。
更新2 我不知道爲什麼這個問題得到很多票下來!
我嘗試在Python這個簡單的數學運算Python的數學精度
>>> math.floor(8.2-0.21)
7.0
>>> math.floor(8.21-0.2)
8.0
>>> math.floor(8.2-0.2)
7.0
第三個應該返回8,但它是返回7?
UPDATE
我已經嘗試在PHP,Ruby和JAVA,我已經得到了相同的結果。
更新2 我不知道爲什麼這個問題得到很多票下來!
的語言您引用IEEE-754 64位二進制浮點或使用底層硬件的浮點,這可能是IEEE-754二進制浮點。
在IEEE-754 64位二進制浮點數中,8.2的最接近的可表示值是8.199999999999999289457264239899814128875732421875,最接近的可表示值爲0.2。200000000000000011102230246251565404236316680908203125.
所以,當你寫8.2 - 0.2
,實際發生的事情是,0.200000000000000011102230246251565404236316680908203125從8.199999999999999289457264239899814128875732421875扣除。結果是略低於8的值,並且稍低於8的值的底面是7.
這裏的教訓是浮點算法通常是近似的,所以在評估具有不連續性的函數時您必須小心(比如地板)或陡坡。您必須設計代碼以接受可能跨越不連續點的結果,或者必須設計計算以避免跨越不連續點的錯誤。
很好的回答,謝謝 – shox
很好的回答... –
你的前兩個例子是可以預料的:
8.2 - 0.21
是7.99
。 7.99
的樓層是7
,這就是返回的內容。請記住,floor(x)
是小於或等於x
的最大整數。 8
大於7.99
,因此不可能被退回。另一方面,7
符合此要求。
8.21 - 0.2
是8.01
。 8.01
的地板是8
- 這裏沒有魔法。
>>> math.floor(8.2-0.2)
7.0
現在,這是更有趣。它有一個事實,即8.2
和0.2
不能準確地用輛彩車代表做,這樣計算的結果或許不是你可能有什麼想法:
>>> 8.2 - 0.2
7.999999999999999
再次,floor()
工作as documented。
你可以看到這個自己使用decimal
爲:
>> from decimal import Decimal
>>> Decimal(0.2)
Decimal('0.200000000000000011102230246251565404236316680908203125')
>>> Decimal(8.2)
Decimal('8.199999999999999289457264239899814128875732421875')
相關:What Every Computer Scientist Should Know About Floating-Point Arithmetic
@EricPostpischil沒關係,你是對的 - 我在想0.8。該錯誤本身來自「8.2」和「0.2」。我會更新答案。 – arshajii
爲什麼它應該是8?樓層函數返回最近的整數向下捨去,所以這兩個例子都是正確的。
8.2 - 0.21 = 7.99,其向下舍入爲7
8.21 - 0.2 = 8.01Hz,其向下舍入爲8
>>> a=0.2
>>> a
0.20000000000000001
>>> b = 8.2
>>> b
8.1999999999999993
>>> b-a
7.9999999999999991
>>> math.floor(b-a)
7.0
由於浮點不精確
你的數學錯了我認爲......也許你想'math.round'? –
你在每個人都回答你之後編輯它,但你的第三個例子是浮點錯誤。 – roippi
我的意思是8.2 - 0.2,我已更新問題 – shox