JavaScript 浮点计算
从 0.1 + 0.2 = 0.30000000000000004 说起,讲清 IEEE 754 双精度浮点的存储结构,以及先乘后除、toFixed 与 decimal.js 等几种处理方式。
0.30000000000000004
在前端进行业务的计算时,出现了一点错误:
var a = 0.1 ;var b = 0.2 ;console.log(a+b);
// 结果0.30000000000000004很奇怪,为什么不直接等于0.3
JavaScript中的数字
数值始终是64位的双精度浮点数,0到51存储数字(片段),52 到 62 存储指数,63 位存储符号。
| 值(aka Fraction/Mantissa) | 指数 | 符号 |
|---|---|---|
| 52 bits(0 - 51) | 11 bits (52 - 62) | 1 bit (63) |
整数会被精确到15位、小数最大数是17位。
对于小数的二进制
系统是将10进制转为二进制再进行计算,0.1的二进制是0001100110...,后面就一直重复0011,0.2的二进制是0011..,也是重复0011。两个二进制再相加,再转为十进制就是0.30000000000000004。
解决方法
1、 先乘后除,缺点是 相乘的结果已经超过了 MAX_SAFE_INTEGER 会出现错误
var x = (0.2 * 10 + 0.1 * 10) / 10;2、指定精度的四舍五入,小数太多,也不是很理想
var a = 0.1 ;var b = 0.2 ;var c = a+b ;console.log(parseFloat(c.toFixed(12)));3、将浮点数转字符串,再模拟实际计算