6.3.5.1 精度を上げて丸め誤差を抑制する

10 進浮動小数点数を使うと、 10 進数表現による誤差を抑制できます (0.1 を正確に表現できるようになります); しかし、ゼロでない 桁が一定の精度を越えている場合には、演算によっては依然として値丸めによる 誤差を引き起こします。 Knuth は、十分でない計算精度の下で値丸めを伴う 浮動小数点演算を行った結果、加算の結合則や分配則における恒等性が崩れて しまう例を二つ示しています:

# Examples from Seminumerical Algorithms, Section 4.2.2.
>>> from decimal import Decimal, getcontext
>>> getcontext().prec = 8

>>> u, v, w = Decimal(11111113), Decimal(-11111111), Decimal('7.51111111')
>>> (u + v) + w
Decimal("9.5111111")
>>> u + (v + w)
Decimal("10")

>>> u, v, w = Decimal(20000), Decimal(-6), Decimal('6.0000003')
>>> (u*v) + (u*w)
Decimal("0.01")
>>> u * (v+w)
Decimal("0.0060000")

decimal モジュールでは、最下桁を失わないように十分に計算精度を 広げることで、上で問題にしたような恒等性をとりもどせます:

>>> getcontext().prec = 20
>>> u, v, w = Decimal(11111113), Decimal(-11111111), Decimal('7.51111111')
>>> (u + v) + w
Decimal("9.51111111")
>>> u + (v + w)
Decimal("9.51111111")
>>> 
>>> u, v, w = Decimal(20000), Decimal(-6), Decimal('6.0000003')
>>> (u*v) + (u*w)
Decimal("0.0060000")
>>> u * (v+w)
Decimal("0.0060000")

ご意見やご指摘をお寄せになりたい方は、 このドキュメントについて... をご覧ください。