起步
浮點數的一個普遍的問題是它們不能精確的表示十進位制數。
>>> a = 4.2
>>> b = 2.1
>>> a + b
6.300000000000001
>>> (a + b) == 6.3
False
>>>
這是由於底層 CPU 和 IEEE 754 標準通過自己的浮點單位去執行算術時的特徵。看似有窮的小數, 在計算機的二進位制表示裡卻是無窮的。
一般情況下,這一點點的小誤差是允許存在的。如果不能容忍這種誤差(比如金融領域),那麼就要考慮用一些途徑來解決這個問題了。
Decimal
使用這個模組不會出現任何小誤差。
>>> from decimal import Decimal
>>> a = Decimal(`4.2`)
>>> b = Decimal(`2.1`)
>>> a + b
Decimal(`6.3`)
>>> print(a + b)
6.3
>>> (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 = 3
... print(a / b)
...
0.765
>>> with localcontext() as ctx:
... ctx.prec = 50
... print(a / b)
...
0.76470588235294117647058823529411764705882352941176
>>>
由於 Decimal
的高精度數字自然也就用字串來做展示和中轉。
總結
總的來說,當涉及金融領域時,哪怕是一點小小的誤差在計算過程中都是不允許的。因此 decimal
模組為解決這類問題提供了方法。