众所周知使用JS进行运算时,偶尔会遇到计算精度不准确的问题,导致实际数值出现差异化,在某些涉及金额的场景这种问题更多的暴露在了用户面前,最近在项目中刚好遇到了在计算金额时精度出现差异化,故而记录一下。
首先JS的计算精度错误主要是因为JS采用的是浮点运算方式而不是整数运算方式,这就会导致精度错误,同时JS内部在计算除法算法时也会出现一些错误,因为JS无法精确的标识一些数字,比如:0.3
在JS中也有一些解决精度问题的方式,比如toFixed()方法,计算保留指定位数的小数,但是由于其计算时会四舍五入故而并不推荐使用,也可以使用toString()方法将数值改为字符串过后在进行运算,方法不止于此,更多的是根据业务场景判断,以下是我在开发中的实际情况。
/**
* @param {number} value
* @param {number} count
* @returns string
*/
keepDecimal(value, count = 2) {
let f = parseFloat(value);
if (isNaN(f)) {
return "";
}
f = Math.floor(value * 100000) / 100000;
let s = f.toString();
let rs = s.indexOf(".");
if (rs < 0) {
rs = s.length;
s += ".";
}
while (s.length <= rs + count) {
s += "0";
}
return s.substring(0, rs + count + 1);
}
keepDecimal(8.075, 4) // 期望获得 8.0750 结果 8.0749
8.075 * 100000 The result is not the expected 807500 but 807499.999999...
# 这就导致后续的补零转换都出现的错误...由于该tool函数所应用的模块较多,在不过多影响的情况下,选择扩大倍率来解决
f = Math.floor(value * 100000) / 100000;
# 修改为
f = Math.floor(value * 10000000) / 10000000; // 问题解决!
总结: 在封装涉及JS运算的函数时,就应该考虑到计算精度问题,提前避免问题出现,尤其是设计金额等数值时
comments