为什么 0.1 + 0.2 ≠ 0.3 ?
因为计算机浮点数的表示法用的是 IEEE 754 标准,这个标准把一个浮点数用 32 位来表示。这 32 位会分成三段,分别是:
- 1 位符号位,称为 sign,简称 S
- 8 位指数位,称为 exponent,简称 E
- 23 位尾数位,称为 mantissa,简称 M
下图是这 32 位的示意图
然后一个浮点数的计算公式是这样的
我猜你看公式基本是看不懂的,我们下面用一个 3.14
这个数字来演示下。
首先 3.14 是一个正数,所以 S = 0
;
那么指数 M 是什么意思呢?它的意思是对于任何数 x,其都可以找到一个 n,使得 2n<=x<=2n+1,那对于 3.14 来说,n 就是 1,因为 21<=3.14<=21+1,然后 M = ((3.14 - 21) / (22-21))23 = 4781506.56,四舍五入,得到 M = 4781507
,这里就产生精度问题了;
最后 E 是多少呢?E = n + 127
把我们得到的 S、M、E 代回到上面的公式中,最后得到的结果是 3.1400001049041748046875。
用同样的方法,我们来计算 0.1、0.2、0.3 的结果,最后得到的结果是:
- 0.1 => 0.10000002384
- 0.2 => 0.20000004768
- 0.3 => 0.2999999
很明显看到 0.1 + 0.2 > 0.3,下图用 JS 代码验证下的确如此
PS 防杠警告:上面有好多公式我是直接看资料得到的,比如 M 的计算公式 和 E = n + 127
,具体原因我也不清楚。