0.2は倍精度浮動小数点数ではないため、最も近い倍精度数に丸められます。つまり、次のようになります。
0.200000000000000011102230246251565404236316680908203125
それはかなり扱いにくいので、代わりに16進数で見てみましょう。
0x0.33333333333334
ここで、この値を1.0から繰り返し減算するとどうなるかを見てみましょう。
0x1.00000000000000
- 0x0.33333333333334
--------------------
0x0.cccccccccccccc
正確な結果は倍精度で表現できないため、丸められます。これにより、次のようになります。
0x0.ccccccccccccd
10進数では、これは正確に次のとおりです。
0.8000000000000000444089209850062616169452667236328125
ここで、このプロセスを繰り返します。
0x0.ccccccccccccd
- 0x0.33333333333334
--------------------
0x0.9999999999999c
rounds to 0x0.999999999999a
(0.600000000000000088817841970012523233890533447265625 in decimal)
0x0.999999999999a
- 0x0.33333333333334
--------------------
0x0.6666666666666c
rounds to 0x0.6666666666666c
(0.400000000000000077715611723760957829654216766357421875 in decimal)
0x0.6666666666666c
- 0x0.33333333333334
--------------------
0x0.33333333333338
rounds to 0x0.33333333333338
(0.20000000000000006661338147750939242541790008544921875 in decimal)
0x0.33333333333338
- 0x0.33333333333334
--------------------
0x0.00000000000004
rounds to 0x0.00000000000004
(0.000000000000000055511151231257827021181583404541015625 in decimal)
したがって、浮動小数点演算に必要な累積丸めにより、観察している非常に小さな非ゼロの結果が生成されることがわかります。丸めは微妙ですが、決定論的であり、魔法ではなく、バグでもありません。時間をかけて学ぶ価値があります。