2015-07-21 58 views
1

這我想象的非常簡單 - 但爲什麼在下面是y的兩個值不是== 0?我認爲十進制模塊的全部要點是擺脫浮塵......以下是將數字作爲變量傳遞的數學例程的極簡化版本。Python十進制模塊 - 不想要的類浮點輸出?

from decimal import * 
getcontext().prec = 2 

q = Decimal(0.01) 

x = Decimal(0.10) * Decimal(0.10) 

y = Decimal(x) - Decimal(q) 

print(x,y, Decimal(y)) 

''' 
x== 0.010 
y== -2.1E-19 
Decimal(y) == -2.1E-19 
''' 

回答

2

float字面0.10是不準確的數學數0.10,用它來初始化Decimal不避float精度問題。

相反,使用字符串初始化Decimal可以給你預期的結果:

x = Decimal('0.10') * Decimal('0.10') 
y = Decimal(x) - Decimal('0.010') 
+0

嘿,謝謝,很高興知道Decimal喜歡的字符串,我根據你的回答編輯了一些問題,儘管 – SomeGuy30145

3

嘗試指定的數字作爲字符串

>>> Decimal('0.10') * Decimal('0.10') - Decimal('0.0100') 
>>> Decimal('0.000') 
+0

嗨,謝謝,很高興知道Decimal喜歡的字符串,但是我根據你的回答編輯了一些問題,儘管 – SomeGuy30145

1

這是在現有的答案提出的觀點的更詳細的解釋。

如果您需要精確的十進制算術,您確實需要擺脫數字文字,如0.1。數字文字通常由IEEE 754 64位二進制浮點數表示。

與0.1最接近的這種數字是0.1000000000000000055511151231257827021181583404541015625。它的平方是0.01000000000000000111022302462515657123851077828659396139564708135883709660962637144621112383902072906494140625,這與0.01最接近,0.010000000000000020816681711721685132943093776702880859375不一樣。

你可以得到什麼回事通過移除prec =2情況下,允許更多精確的輸出更清晰的視野:

from decimal import * 
q = Decimal(0.01) 
x = Decimal(0.10) * Decimal(0.10) 
y = Decimal(x) - Decimal(q) 
print(q) 
print(x) 
print(y) 

輸出:

0.01000000000000000020816681711721685132943093776702880859375 
0.01000000000000000111022302463 
9.020562075127831486705690622E-19 

如果你曾經使用字符串常量,如由其他響應建議,轉換爲Decimal將直接完成,而不需要經過二進制浮點。 0.1和0.01都可以在Decimal中精確表示,所以不會有舍入誤差。