0.2 不是双精度浮点数,所以四舍五入到最接近的双精度数,即:
0.200000000000000011102230246251565404236316680908203125
这相当笨拙,所以让我们用十六进制来看看它:
0x0.33333333333334
现在,让我们看看当这个值被反复从 1.0 中减去时会发生什么:
0x1.00000000000000
- 0x0.33333333333334
--------------------
0x0.cccccccccccccc
确切的结果不能用双精度表示,所以它是四舍五入的,它给出:
0x0.ccccccccccccd
在十进制中,这正是:
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)
因此,我们看到浮点运算所需的累积舍入会产生您正在观察的非常小的非零结果。舍入是微妙的,但它是确定性的,不是魔术,也不是错误。值得花时间去学习。