JS浮点数精准计算问题

在工作中遇到这种浮点数计算精度问题,例如
0.1 + 0.2 不等于 0.3

1
2
>  0.1+0.2
<· 0.30000000000000004

原因

在 JavaScript 里,数字均为基于 IEEE 754 标准的双精度 64 位的浮点数,并且只要采用 IEEE 754 的语言都有该问题。
在 JavaScript 使用 64 位存储数字类型,因此超出的会舍去。舍去的部分就是精度丢失的部分。


sign bit(符号): 用来表示正负号

exponent(指数): 用来表示次方数

mantissa(尾数): 用来表示精确度

六十四位中符号位占一位,整数位占十一位,其余五十二位都为小数位,也就是说一个数字的范围只能在 -(2^53 -1) 至 2^53 -1 之间。

0.1 + 0.2 算不准的原因也在于此。浮点数用二进制表达时是无穷的,且最多 53 位,必须截断,进而产生误差。

解决办法

  1. 取巧方法 ~
1
2

parseFloat((0.1+0.2).toFixed(2)); //js 浮点计算 bug,取两位小数精度(银行家算法)
  1. 将数字转成整数,但是这种方法对大数支持的依然不好
1
2
3
4
5
6
7

function addFloatNum(num1, num2) {
const num1Digits = (num1.toString().split('.')[1] || '').length;
const num2Digits = (num2.toString().split('.')[1] || '').length;
const baseNum = Math.pow(10, Math.max(num1Digits, num2Digits));
return (num1 _ baseNum + num2 _ baseNum) / baseNum;
}
  1. 第三方库 Math.js , bignumber.js,big.js
1
2