为什么 1.1+0.2 = 1.3?
2023-11-28 18:01:21
也许你知道 0.1 + 0.2 === 0.3 为 false,但是 1.1 + 0.2 === 1.3 呢?明明都是浮点数的加法,为什么表现出来的效果不一样呢?让我们一步步来揭晓谜底。
首先我们需要知道十进制是怎么转为二进制的,下面以 6.1 为例来进行说明。
- 整数部分
不断的将商除以二得到余数,直到商为0。
商 | 余数
6 | 0
3 | 1
1 | 1
0 | 1
反转余数即为整数部分的二进制表示,也就是 110 。
- 小数部分
不断的乘以二然后拿掉整数部分,直到积为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.1:0 01111110 110000000000000000000000
0.2:0 01111110 100110011001100110011001
将两个小数位相加,得到:
110000000000000000000000 + 100110011001100110011001 = 10001111100110101010010001101001
将结果存放在一个临时寄存器中,然后将符号位、指数位和小数位组合起来,得到最终结果:
0 01111111 10001111100110101010010001101001
将二进制表示转换成十进制,得到:
1.3
这就是为什么 1.1 + 0.2 会等于 1.3 而不是 1.3000000000000003 的原因。
值得注意的是,由于浮点数的有限精度,某些计算可能会产生误差。为了避免这些误差,可以使用大精度浮点数类型,如双精度浮点数或四精度浮点数。