丸め誤差がどのように蓄積されているかをよりよく理解し、より低いレベルで何が起こっているかについてより多くの洞察を得るために、ここに簡単な説明があります:
IEEE 754 倍精度標準が基礎となるソフトウェア/ハードウェアによってデフォルトの丸めモードで使用されていると仮定します (最も近い偶数に丸める)。
1/5 は底 2 で無限に繰り返されるパターンで書くことができます
0.00110011001100110011001100110011001100110011001100110011...
しかし、浮動小数点では、最上位 1 ビットから始まる仮数を有限のビット数 (53) に丸める必要があります。
そのため、0.2 を 2 進数で表すと、小さな丸め誤差があります。
0.0011001100110011001100110011001100110011001100110011010
10 進数表現に戻ると、この丸め誤差は 1/5 をわずかに超える 0.00000000000000011102230246251565404236316680908203125 に相当します。
0.2+0.2 は 2*0.2 に似ているため、最初の操作は正確であり、追加のエラーは発生しません。これは分数ポイントをシフトするようなものです。
0.0011001100110011001100110011001100110011001100110011010
+ 0.0011001100110011001100110011001100110011001100110011010
---------------------------------------------------------
0.0110011001100110011001100110011001100110011001100110100
しかしもちろん、2/5 を超える超過分は 2 倍になります。
3 番目の演算 0.2+0.2+0.2 は、この 2 進数になります。
0.011001100110011001100110011001100110011001100110011010
+ 0.0011001100110011001100110011001100110011001100110011010
---------------------------------------------------------
0.1001100110011001100110011001100110011001100110011001110
しかし残念なことに、54 ビットの有意桁 (先頭の 1 と末尾の 1 の間のスパン) が必要なため、結果を double として表すには別の丸め誤差が必要です。
0.10011001100110011001100110011001100110011001100110100
デフォルトでは、浮動小数点数は完全に引き分けの場合でも最も近い値に丸められるため、数値が上に丸められていることに注意してください。すでに過剰なエラーが発生していたので、運が悪かったため、エラーが連続して消滅するのではなく蓄積されました...
したがって、3/5 を超える超過分は 0.000000000000000088817841970012523233890533447265625 になります。
を使用して、このエラーの蓄積を少し減らすことができます
x1 = i / 5.0
5 は float で正確に表され (2 進数では 101.0、有効桁数 3 ビットで十分)、i の場合も同様 (2^53 まで) であるため、除算の実行時に 1 つの丸め誤差が発生し、IEEE 754 は、可能な限り最も近い表現を取得することを保証します。
たとえば、3/5.0 は次のように表されます。
0.10011001100110011001100110011001100110011001100110011
10 進数に戻すと、値はデフォルトで表されます。
どちらのエラーも非常に小さいことに注意してください。ただし、2 番目のケースでは 3/5.0 であり、0.2+0.2+0.2 の 4 分の 1 です。