2013-04-10 79 views
3
我只是使用Python作爲鈣

,我看到這個Python的舍入誤差

Python 2.7.3 (default, Aug 1 2012, 05:14:39) 
[GCC 4.6.3] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> 62 * 41.2 * 2/250 
20.435200000000002 
>>> 62 * 4.12 * 2/25 
20.4352 
>>> 

只是可以肯定我解僱下面的代碼通過GCC但沒有告訴我上述行爲。我知道這可能是四捨五入的,但它應該是統一的。爲什麼Python在數學上加起來的00000000002不應該在那裏。

C/C++代碼

#include <stdio.h> 
int main() { 
    printf ("%lf %lf \n", 62 * 41.2 * 2/250, 62 * 4.12 * 2/25); 
} 

結果

20.435200 20.435200

如果有人好奇,他們屬於某個發動機排量計算比較:)

+2

浮點運算,它的工作原理是這樣的大多數語言:Python的http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html應用一些四捨五入到打印輸出你可以在這裏看到http://docs.python.org/2/tutorial/floatingpoint.html,但是在兩種情況下存儲的數字都只有浮點允許的數量。 – 2013-04-10 15:41:20

+0

這是浮點差異。由於內部表示,「41.2/10!= 4.12」。 – mgilson 2013-04-10 15:44:19

回答

8

除了@Ashwini喬杜裏回答,

問:

爲什麼蟒蛇相加後00000000002數學時,它不應該在那裏

答:

因爲在機器值確切。這不是Python中的錯誤或代碼中的錯誤。在支持二進制浮點運算的所有語言中,您將看到完全相同的問題。但是,不同的語言可能會以不同的方式顯示(四捨五入)。

試試這個:

0.1 + 0.2 

你會得到

0.30000000000000004 

這是因爲0.1不能以二進制形式來代表完全相同。在基體2,或二進制,0.1是無限重複的數字

0.0001100110011001100110011001100110011001100110011... 

所以,Python的決定圓這一關代替。我建議你閱讀更多here

+0

它是「確切的」,它不只是十進制,因此你得到很多小數值的舍入誤差。 – 2013-04-10 15:49:31

3

使用的特定號碼print也在python中。

In [87]: print 62 * 41.2 * 2/250 
20.4352 

In [88]: print 62 * 41.2 * 2/25 
204.352 

Python的外殼採用repr顯示輸出,這就是爲什麼你得到奇怪的輸出:

In [89]: print repr(62 * 41.2 * 2/250) 
20.435200000000002 

print使用str

In [90]: print str(62 * 41.2 * 2/250) 
20.4352 
3

別擔心,C實際上並是相同的,你只是沒有打印出來,因爲你表現得太幾個數字:

#include <stdio.h> 
int main() { 
    printf ("%.16lf %.16lf \n", 62 * 41.2 * 2/250, 62 * 4.12 * 2/25); 
} 

20.4352000000000018 20.4351999999999983 
0

你被暴露在通常使用二進制浮點數的奇怪之處;這些對大多數計算機語言都很常見。對產出的不同舍入策略可以隱藏這些問題,但它們仍然存在。理解這些的常用參考是"What Every Computer Scientist Should Know About Floating-Point Arithmetic",但也有一個Python特定指南"Floating Point Arithmetic: Issues and Limitations"

Python有幾個解決方案可用於在需要時獲得更精確的結果。第一個是decimal module,它使用十進制數而不是二進制數。

>>> from decimal import Decimal 
>>> Decimal(62) * Decimal("41.2") * Decimal(2)/Decimal(250) 
Decimal('20.4352') 
>>> Decimal(62) * Decimal("4.12") * Decimal(2)/Decimal(25) 
Decimal('20.4352') 

還有以跟蹤一個獨立的分子和分母的fractions module,所以任何可能的部分可以表示。

>>> from fractions import Fraction 
>>> Fraction("41.2") 
Fraction(206, 5) 
>>> Fraction(62) * Fraction("41.2") * Fraction(2)/Fraction(250) 
Fraction(12772, 625) 
>>> Fraction(62) * Fraction("4.12") * Fraction(2)/Fraction(25) 
Fraction(12772, 625) 
>>> float(Fraction(12772, 625)) 
20.4352 
2

嘗試使用十進制

>>> from decimal import Decimal 
>>> dec = Decimal('41.2') 
>>> 62 * dec * 2/250 
Decimal('20.4352') 

請注意,您必須使用一個字符串作爲參數。如果你使用float作爲參數,它會失敗。

>>> dec1 = Decimal(41.2) 
>>> dec2 = Decimal('41.2') 
>>> dec1 == dec2 
False 
>>> print dec1, dec2 
41.2000000000000028421709430404007434844970703125 41.2