今天同事发现一个问题如下,小数相加精度出现了问题
这两个数相加理论上应是 31699.9603
但是js算出来却是 316999.96030000004
具体原理不明白,也没去研究,直接上我的处理办法
console.log(280530.9303 + 36469.03)
var num = add(280530.9303, 36469.03)
console.log(num)
function add(a, b) {
// 数字转成字符串
var stra = a.toString()
var strb = b.toString()
console.log(stra, strb)
// 计算两个浮点数的小数位
var lena = stra.substr(stra.indexOf('.') + 1).length
var lenb = strb.substr(strb.indexOf('.') + 1).length
// 最大小数位 如果最大是4位小数,则两数*10000再计算
var maxLen = lena > lenb ? lena : lenb
console.log(lena, lenb, maxLen)
// 小数扩大变成整数进行加计算
var pow = Math.pow(10, maxLen)
console.log(pow)
var tempSum = a * pow + b * pow
console.log(tempSum)
var strTempSum = tempSum.toString()
// 扩大的数相加完毕后,理论上再除以10000即可得到结果,不过除法也有可能导致精度问题,所以选择字符串处理
// 将相加后的数截取 最后4(最大小数位)个字符作为小数位,拼接达到目的
// 字符串形式达到处理为小数的效果
var result =
strTempSum.slice(0, strTempSum.length - maxLen - 1) +
'.' +
strTempSum.slice(strTempSum.length - maxLen)
console.log(result)
return parseFloat(result)
}
经过处理后结果如图,达到目的。OK!
注:通过看别的博客,如果数字扩大后大于Math.pow(2, 53) ,则相加可能还会有问题,我没做尝试。