3.2執行精確的浮點數運算
阿新 • • 發佈:2022-03-05
問題
你需要對浮點數執行精確的計算操作,並且不希望有任何小誤差的出現。
解決方案
浮點數的一個普遍問題是它們並不能精確的表示十進位制數。並且,即使是最簡單的數學運算也會產生小的誤差,比如:
a = 2.1
b = 4.2
c = a + b
print(c) # ->6.300000000000001
print(round(c, 2)) # ->6.3
這些錯誤是底層CPU和IEEE754標準通過自己的浮點單位去執行算術時的特徵。由於Python的浮點資料型別使用底層表示儲存資料,因此你沒辦法去避免這樣的誤差。
如果你想更加精確(並能容忍一定的效能損耗),你可以使用decimal模組:
from decimal import Decimal
a = Decimal('4.2')
b = Decimal('2.1')
print((a + b) == Decimal('6.3')) # _>True
初看起來,上面的程式碼好像有點奇怪,比如我呢用字串來表示數字。然而,Decimal物件會像普通浮點數一樣的工作(支援所有的常用數學運算)。如果你列印它們或者在字串格式化函式中使用它們,看起來跟普通數字沒有什麼兩樣。
decimal模組的一個主要特徵是允許你控制計算的每一方面,包括數字位數和四捨五入運算。為了這樣做,你先得建立一個本地上下文並更改它的設定,比如:
from decimal import Decimal, localcontext a = Decimal('1.3') b = Decimal('1.7') print(a / b) # ->0.7647058823529411764705882353 with localcontext() as ctx: ctx.prec = 50 print(a/b) # ->0.76470588235294117647058823529411764705882352941176 with localcontext() as ctx: ctx.prec = 3 print(a/b) # ->0.765