1. 程式人生 > 其它 >3.2執行精確的浮點數運算

3.2執行精確的浮點數運算

問題

​ 你需要對浮點數執行精確的計算操作,並且不希望有任何小誤差的出現。

解決方案

​ 浮點數的一個普遍問題是它們並不能精確的表示十進位制數。並且,即使是最簡單的數學運算也會產生小的誤差,比如:

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