精度丢失场景
数值计算在前端的应用还不算少,但涉及 浮点数 参与计算时可能会出现精度丢失,如下:
加( + )
- 正常计算:0.1 + 0.2 = 0.3
- JavaScript 计算:0.1 + 0.2 = 0.30000000000000004
减( - )
- 正常计算:1 - 0.9 = 0.1
- JavaScript 计算:1 - 0.9 = 0.09999999999999998
乘( * )
- 正常计算:0.0532 * 100 = 5.32
- JavaScript 计算:0.0532 * 100 = 5.319999999999999
除( / )
- 正常计算:0.3 / 6 = 0.05
- JavaScript 计算:0.3 / 6 = 0.049999999999999996
保留指定小数位
除了上述对涉及浮点数计算、超过最值的场景之外,我们通常还会对数值进行保留指定小数位的处理,而部分开发者可能会直接使用 Number.prototype.toFixed 来实现,但这个方法却并不能保证我们期望的效果,例如保留小数位时需要进行 四舍五入 时就会有问题,如下:
console.log((1.595).toFixed(2)); // 1.59 ——> 期望为:1.60
console.log((1.585).toFixed(2)); // 1.58 ——> 期望为:1.59
console.log((1.575).toFixed(2)); // 1.57 ——> 期望为:1.58
console.log((1.565).toFixed(2)); // 1.56 ——> 期望为:1.57
console.log((1.555).toFixed(2)); // 1.55 ——> 期望为:1.56
console.log((1.545).toFixed(2)); // 1.54 ——> 期望为:1.55
console.log((1.535).toFixed(2)); // 1.53 ——> 期望为:1.54
console.log((1.525).toFixed(2)); // 1.52 ——> 期望为:1.53
console.log((1.515).toFixed(2)); // 1.51 ——> 期望为:1.52
console.log((1.505).toFixed(2)); // 1.50 ——> 期望为:1.51
big.js
为了解决上述问题,我们可以使用 big.js 库来处理,它是一个精确的 JavaScript 库,它可以处理任意精度的浮点数,并且提供了一系列精度丢失的解决方案
安装
npm install big.js
plus
0.1 + 0.2; // 0.30000000000000004
x = new Big(0.1);
y = x.plus(0.2); // '0.3'
Big(0.7).plus(x).plus(y); // '1.1'
minus
0.3 - 0.1; // 0.19999999999999998
x = new Big(0.3);
x.minus(0.1); // '0.2'
times
0.6 * 3; // 1.7999999999999998
x = new Big(0.6);
y = x.times(3); // '1.8'
Big("7e+500").times(y); // '1.26e+501'
div
x = new Big(355);
y = new Big(113);
// x÷y
x.div(y); // '3.14159292035398230088'
// 保留两位小数
Big.DP = 2;
x.div(y); // '3.14'
x.div(5); // '71'