x = 4.2 - 0.1
vb.net給4.1000000000000005
蟒蛇給4.1000000000000005
爲什麼簡單的浮點算術運算會返回VB.Net和Python中意外(不準確)的結果?
Excel中給出了4.1
Google calc給4.1
這是什麼情況的原因是什麼?
x = 4.2 - 0.1
vb.net給4.1000000000000005
蟒蛇給4.1000000000000005
爲什麼簡單的浮點算術運算會返回VB.Net和Python中意外(不準確)的結果?
Excel中給出了4.1
Google calc給4.1
這是什麼情況的原因是什麼?
你必須記住,在二進制,4.1 = 4 + 1/10。 1/10是二進制的無限重複和,很像1/9是十進制的無限和。
0.000110011001100 ...二進制數是0.1的十進制數。 http://www.exploringbinary.com/binary-converter/ – 2009-10-20 15:24:42
真的沒有問題。這只是漂浮工作的方式(他們的內部二進制表示)。總之:
>>> from decimal import Decimal
>>> Decimal('4.2')-Decimal('0.1')
Decimal('4.1')
+1解決方法。 – 2009-10-20 14:33:30
在vb.net中,您可以通過使用十進制類型,而不是避免這個問題:
Dim x As Decimal = 4.2D - 0.1D
結果是4.1。
>>> x = 4.2 - 0.1
>>> x
4.1000000000000005
>>>>print(x)
4.1
這是因爲how numbers are stored internally。
計算機用二進制表示數字,而不是十進制數,就像我們人類習慣的那樣。使用浮點數時,計算機必須將近似爲以達到最接近的二進制浮點值。
Almost all machines today(2000年11月)使用IEEE-754浮點運算,幾乎所有平臺都將Python映射到IEEE-754「雙精度」映射。 754雙精度包含53位精度,因此在輸入時,計算機會努力將0.1轉換爲最接近的分數,它可以是
J/2***N*
,其中J
是一個包含正好53位的整數。
如果print
數量it will show the approximation,截斷爲正常值。例如,實數值0.1
是0.1000000000000000055511151231257827021181583404541015625
。
如果你真的需要基於十進制數(如果你不知道這個問題的答案,你不),您可以使用(在Python)decimal.Decimal
:
>>> from decimal import Decimal
>>> Decimal("4.2") - Decimal("0.1")
Decimal("4.1")
二進制浮點算法有很多這樣的驚喜。 「0.1」的問題在下面的「Representation Error」部分詳細解釋。 請參閱The Perils of Floating Point瞭解其他常見驚喜的更完整說明。
就像接近尾聲說的那樣,「沒有簡單的答案。」但是,不要過分警惕浮點!Python浮點運算中的錯誤是從浮點硬件繼承而來的,並且在大多數機器上,每個操作的執行次數不會超過1個部分,即
2**53
。這對於大多數任務來說已經足夠了,但是您需要記住它不是十進制算術,並且每個浮點操作都會遇到新的舍入錯誤。雖然存在病態情況,但對於大多數臨時使用的浮點運算,如果您只是將最終結果顯示爲您期望的小數位數,您會最終看到預期的結果。
str()
通常就足夠了,而爲了更好地控制,請參閱Format String Syntax中str.format()
方法的格式說明符。
Google calc explicity將輸入轉換爲浮點數,然後截斷精度問題。請參閱http://en.wikipedia.org/wiki/Floating_point#Minimizing_the_effect_of_accuracy_problems。 – 2009-10-20 14:30:43
請閱讀三次或四次:http://docs.sun.com/source/806-3568/ncg_goldberg.html – nlucaroni 2009-10-20 14:31:09
重複。 http://stackoverflow.com/questions/1089018/why-cant-decimal-numbers-be-represented-exactly-in-binary,http://stackoverflow.com/questions/177506/why-do-i-see- a-double-variable-initialized-some-value-like-21-4-as-21-39999961,http://stackoverflow.com/questions/963873/1-265-10000-126499-99999999999等 – 2009-10-20 14:54:20