- 先看一个问题:
0.1 + 0.2 !== 0.3
计算机进行加法计算时先将数字转化成二进制,运算完成后再把结果转成十进制。
计算机中二进制表示浮点数是无限循环,如 0.1
二进制表示
0.0001100110011001100110011001100110011001100110011001101
- 计算过程:
乘以2 | 整数部分 |
---|---|
0.1 * 2 = 0.2 | 0 |
0.2 * 2 = 0.4 | 0 |
0.4 * 2 = 0.8 | 0 |
0.8 * 2 = 1.6 | 1 |
0.6 * 2 = 1.2 | 1 |
乘二取整,顺序排列: 将小数乘以2,得到的整数作为二进制表示第一位,小数部分再乘以2,得到整数部分作为二进制表示的第二位,小数部分再乘以2,直到小数部分为0。
特殊情况,小数部分一直不为0,即为无限循环,0.1
就是这样的数。
根据IEEE 754 标准,浮点数的存储位数为64,超过会发生精度丢失,变成
0.0001100110011001100110011001100110011001100110011001101
0.1
二进制转化成十进制,变成
0.100000000000000002
回到上面的问题,0.1 + 0.2
结果变成 0.30000000000000004
- 解决方式:
parseFloat((0.1+0.2).toFixed(12))
// 0.3
toFixed
将数字四舍五入到指定小数位toFixed
对整数无效,先转换为浮点数toFixed
的bug
对第三位小数小于等于5舍去,大于等于6会进位
改进方式:
Math.round((0.1+0.2)*10)/10;
// 0.3