原因
这和计算机存储机制有关系,在计算机中,存储双精度浮点数的时候,会把十进制转成二进制,再根据计算机存储二进制的规则存储,因为计算机存储时有位数限制,在转二进制的浮点数的时候某些时候会出现无限循环,会造成二进制的四舍五入(0舍1入)从而在二进制再去转十进制的时候就会出现计算误差;
解决方法
理论上利用计算机有限的存储空间来存储无限的小数是不可能保证精确度的,但我们可以处理一下得到我们的期望值:
当你拿到 1.4000000000000001 这样的数据要展示时,建议使用 toPrecision 凑整并 parseFloat 转成数字后再显示,如下:
parseFloat(1.4000000000000001.toPrecision(12)) === 1.4 // True
封装方法:
function strip(num,precision = 12){
return +parseFloat(num.toPrecision(precision));
}
对于运算类操作,如 +-*/,就不能使用 toPrecision 了。正确的做法是把小数转成整数后再运算。以加法为例:
/**
* 精确加法
*/
function add(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;
}
网友评论