返回

为什么 1.1+0.2 = 1.3?

前端

也许你知道 0.1 + 0.2 === 0.3 为 false,但是 1.1 + 0.2 === 1.3 呢?明明都是浮点数的加法,为什么表现出来的效果不一样呢?让我们一步步来揭晓谜底。

首先我们需要知道十进制是怎么转为二进制的,下面以 6.1 为例来进行说明。

  1. 整数部分

不断的将商除以二得到余数,直到商为0。

| 余数
6   | 0
3   | 1
1   | 1
0   | 1

反转余数即为整数部分的二进制表示,也就是 110

  1. 小数部分

不断的乘以二然后拿掉整数部分,直到积为0。

积   | 整数部分 | 余数
0.1 * 2 = 0.2   | 0 | 0.2
0.2 * 2 = 0.4   | 0 | 0.4
0.4 * 2 = 0.8   | 0 | 0.8
0.8 * 2 = 1.6   | 1 | 0.6
0.6 * 2 = 1.2   | 1 | 0.2
0.2 * 2 = 0.4   | 0 | 0.4
0.4 * 2 = 0.8   | 0 | 0.8
0.8 * 2 = 1.6   | 1 | 0.6

反转余数即为小数部分的二进制表示,也就是 .0011011001101101101101101101101

将整数部分与小数部分拼接起来即为 6.1 的二进制表示:

110.0011011001101101101101101101101

为了在计算机中表示浮点数,IEEE 754 标准定义了浮点数的格式。浮点数由三部分组成:符号位、指数位和小数位。符号位表示数字是正数还是负数。指数位表示数字的阶码,即小数点的位置。小数位表示数字的小数部分。

符号位(1位)    指数位(8位)    小数位(23位)

将 6.1 的二进制表示转换成 IEEE 754 标准格式:

符号位:0(正数)

指数位:127(11111111)

小数位:0011011001101101101101101101101

最终,6.1 的 IEEE 754 标准格式为:

0 11111111 0011011001101101101101101101101

当计算机执行浮点数加法时,它首先将两个浮点数转换成 IEEE 754 标准格式。然后,它将两个小数位相加,并将结果存放在一个临时寄存器中。最后,它将符号位、指数位和小数位组合起来,得到最终结果。

在我们的例子中,1.1 和 0.2 的 IEEE 754 标准格式如下:

1.10 01111110 110000000000000000000000
0.20 01111110 100110011001100110011001

将两个小数位相加,得到:

110000000000000000000000 + 100110011001100110011001 = 10001111100110101010010001101001

将结果存放在一个临时寄存器中,然后将符号位、指数位和小数位组合起来,得到最终结果:

0 01111111 10001111100110101010010001101001

将二进制表示转换成十进制,得到:

1.3

这就是为什么 1.1 + 0.2 会等于 1.3 而不是 1.3000000000000003 的原因。

值得注意的是,由于浮点数的有限精度,某些计算可能会产生误差。为了避免这些误差,可以使用大精度浮点数类型,如双精度浮点数或四精度浮点数。