title: JS 浮点数相加出现精度不准确问题
JS 浮点数相加出现精度不准确问题
场景还原:最近在做公司的一个点餐项目时,遇到添加商品计算总价的需求,自然而然的用最原始的方法实现。但当我计算到6 + 0.01 + 0.01 + 0.02 时,居然不等于6.04。一开始及其懵逼反复检查了自己的逻辑代码,发现都没问题。最后只能找度娘,发现原来这是js 本身的问题, 由于存在二进制和十进制的转换问题,具体的位数会发生变化 。我默默打开浏览器控制台,验证一下,果不其然,下面的浏览器控制台的打印结果:
对于这个问题,有两个解决办法:1,toFixed() 2,自定义方法转换
方案一:toFixed()
将每次相加的和用toFixed()这个方法转一下,就可以得到保留两位小数的浮点数。这个方法比较简单,适合用于精度要求不高的场景
方案二:自定义函数
先贴代码:
getSum:function (num1, num2) {
let sq1 = 0
let sq2 = 0
let m = 0
try {
sq1 = num1.toString().split('.')[1].length
} catch (error) {
sq1 = 0
}
try {
sq2 = num2.toString().split('.')[1].length
} catch (error) {
sq2 = 0
}
m = Math.pow(10, Math.max(sq1, sq2))
return (num1 * m + num2 * m) / m
}
注意:Math.pow,Math.max,可以先了解一下js的这个内置方法,在这里就不多阐述了
思路:这个方法的逻辑就是传入两个要求和的数字(前提必须是数字),首先假设传入的是小数,通过toString().split('.')[1].length,将小数转为字符串然后以(‘ . ’)切割字符串并且取到后半部分的长度,所以sq1,sq2分别取到的是两个小数的小数位数。Math.max(sq1, sq2)得到最大的小数位数,Math.pow(10, Math.max(sq1, sq2))得到10的最大小数位数幂。
总结:把需要计算的数字乘以 10 的 n 次幂,换算成计算机能够精确识别的整数,然后再除以 10 的 n 次幂,这样就能得到精度准确的小数