2009-10-20 84 views
3
x = 4.2 - 0.1 

vb.net給4.1000000000000005
蟒蛇給4.1000000000000005爲什麼簡單的浮點算術運算會返回VB.Net和Python中意外(不準確)的結果?

Excel中給出了4.1
Google calc4.1

這是什麼情況的原因是什麼?

+2

Google calc explicity將輸入轉換爲浮點數,然後截斷精度問題。請參閱http://en.wikipedia.org/wiki/Floating_point#Minimizing_the_effect_of_accuracy_problems。 – 2009-10-20 14:30:43

+7

請閱讀三次或四次:http://docs.sun.com/source/806-3568/ncg_goldberg.html – nlucaroni 2009-10-20 14:31:09

+3

重複。 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

回答

13

Float/double precision.

你必須記住,在二進制,4.1 = 4 + 1/10。 1/10是二進制的無限重複和,很像1/9是十進制的無限和。

+0

0.000110011001100 ...二進制數是0.1的十進制數。 http://www.exploringbinary.com/binary-converter/ – 2009-10-20 15:24:42

4

真的沒有問題。這只是漂浮工作的方式(他們的內部二進制表示)。總之:

>>> from decimal import Decimal 
>>> Decimal('4.2')-Decimal('0.1') 
Decimal('4.1') 
+0

+1解決方法。 – 2009-10-20 14:33:30

1

在vb.net中,您可以通過使用十進制類型,而不是避免這個問題:

Dim x As Decimal = 4.2D - 0.1D 

結果是4.1。

10
>>> 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.10.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 Syntaxstr.format()方法的格式說明符。

+1

1.1的實際值是0.1000000000000000055511151231257827021181583404541015625。 =>關閉1.0 – foosion 2009-10-20 15:22:19

+0

@foosion:良好的捕獲。 – voyager 2009-10-20 15:30:30

相關問題