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")
ご意見やご指摘をお寄せになりたい方は、 このドキュメントについて... をご覧ください。