1. 程式人生 > >python執行精確的小數計算

python執行精確的小數計算

在進行浮點數計算時它們無法精確表達出所有的十進位制小數位。

a = 4.1
b = 5.329
print(a+b)

9.428999999999998

這些誤差實際上是底層CPU的浮點運算單元和IEEE754浮點數算數標準的一種“特性”。python的浮點數型別儲存的資料採用的是原始表示形式,因此使用float例項時就不能避免這樣的誤差。

我們可以使用decimal模組避免這種操作(如果不介意犧牲下效能):

from decimal import Decimal
a = Decimal('4.1')
b = Decimal('5.329')
print(a+b)

9.429

注意Decimal的引數必須是字串,不能是浮點型,否則誤差依舊存在。

decimal模組的主要功能是允許控制計算過程中的各個方面,包括數字的尾數和四捨五入。

from decimal import Decimal
from decimal import localcontext
a = Decimal(4.1)
b = Decimal(5.329)
print(a/b)
print('================')
with localcontext() as ctx:
    ctx.prec = 3
    print(a/b)

0.7693751172827922400071261708
================
0.769

getcontext也可以實現和localcontext一樣的功能

from decimal import Decimal, getcontext
a = Decimal(4.1)
b = Decimal(5.329)
getcontext().prec = 3
print(a/b)

0.769

誤差我們不能完全消除,我們只能盡力優化演算法,使得誤差儘可能小。在大數和小數相加時要格外注意。

nums = [3.21e+18, 1, -3.21e+18]
print(sum(nums))
print('=========================')
import math
res = math.fsum(nums)
print(res)

0.0
=========================
1.0