为什么双倍的 1/3 是 0.33333333333333331
用二进制表示 1/3 的最接近的方法是:0.0101010101... 这与系列 1/4 + (1/4)^2 + (1/4)^3 + (1/4)^ 相同4...
当然,这受到您可以存储在 double 中的位数的限制。double 是 64 位,但其中一个是符号位,另一个 11 代表指数(把它想象成科学记数法,但是是二进制的)。所以其余的,称为尾数或有效位是 52 位。假设以 1 开始,然后为每个后续的 1/4 幂使用两位。这意味着您可以存储: 1/4 + 1/4^2 + ... + 1/4 ^ 27 即 0.33333333333333331
为什么乘以 3 舍入到 1
所以 1/3 以二进制表示并受双精度大小的限制: 0.010101010101010101010101010101010101010101010101010101 我并不是说它是这样存储的。就像我说的那样,您存储从 1 开始的位,并为指数和符号使用单独的位。但我认为考虑如何在 base 2 中实际编写它是有用的。
让我们坚持使用这种“数学家的二进制”表示并忽略双精度数的大小限制。你不必这样做,但我觉得很方便。如果我们想将此近似值取为 1/3 并乘以 3,这与移位乘以 2 然后添加您开始的内容相同。这给了我们 1/3 * 3 = 0.1111111111111111111111111111111111111111111111111111
但是双倍存储可以吗?不,请记住,在第一个 1 之后只能有 52 位尾数,而那个数字有 54 个。所以我们知道它会被四舍五入,在这种情况下四舍五入到 1。
为什么十进制你会得到 0.9999999999999999999999999999
使用十进制,您可以获得 96 位来表示一个整数,另外的位表示最多 10 的 28 次幂的指数。所以即使最终它全部存储为二进制,这里我们使用的是 10 的幂,所以考虑一下是有意义的以 10 为基数的数字。 96 位最多可以表示 79,228,162,514,264,337,593,543,950,335,但要表示 1/3,我们将使用所有 3,最多 28 个,我们可以将其移到小数点右侧: 0.3333333333333333333333333333。
将这个 1/3 的近似值乘以 3 可以得到一个可以精确表示的数字。它只有 28 个 9,全部移到小数点右侧:0.9999999999999999999999999999。因此,与双精度数不同,此时没有第二轮舍入。