1.现象
让我们看下几个案例:
1.55.toFixed(1) => 1.6
2.55.toFixed(1) => 2.5
解释:
toFixed()的作用是保留小数位数,多余的位数进行四舍五入;
但是2.55应该四舍五入为2.6,为什么这里是2.5;
根本原因是小数在计算机中存储不一定准确,而计算机存储的位数是有限的; 2.55.toPrecision(20) => '2.5499999999999998224'
正如你所看到的,计算机上实际存储的并不完全是2.55
2.根本原因:存储可能不准确
小数部分是1/(2^n)的,都可以在计算机中精确表示.
0.25.toPrecision(20) => '0.25000000000000000000' 1/(2^2)
0.125.toPrecision(20) => '0.12500000000000000000' 1/(2^3)
0.0625.toPrecision(20) => '0.06250000000000000000' 1/(2^4)
3.次要原因:计算可能不准确
例1:0.2 + 0.3 === 0.5 => true
0.2.toPrecision(20) => '0.20000000000000001110'
0.3.toPrecision(20) => '0.29999999999999998890'
0.2实际存储的值偏大,0.3实际存储的值偏小,一来一去反而精确了。
例2:0.3 - 0.2 === 0.1 => false 0.09999999999999998
0.2实际存储的值偏大,0.3实际存储的值偏小,偏小的减去偏大的,比实际值更小了
4.次要原因:表示可能不准确
JS引擎可能会对一些值使用近似值
const a = 0.2; //=> 实际存储的是 0.20000000000000001110
console.log(0.2); //=> 0.2
0.2 ===0.20000000000000001110 => true
5.解决方案
使用第三方库 或者 存储为字符串,遍历字符串计算(计算效率会降低)
第三方库:decimal.js
www.npmjs.com/package/dec…