JavaScript在进行包含小数的数值运算时,常因浮点数表示法导致精度丢失,出现多余的小数位。本文介绍两种解决方案:一是使用toFixed()进行低精度截断,适用于对精度要求不高的场景;二是通过乘以10的n次方转换为整数运算后再还原的高精度算法,适用于需要精确结果且希望控制小数位数的场景。
当涉及包含小数的数值进行运算时,计算结果往往并非预期值,而是出现精度丢失现象,表现为小数点后出现大量无意义的位数。
问题所在:
res.orderColorDeliveryRecords.forEach((item) => {
//计算金额
item.money = (item.price * item.amount);
if(!item.cusTypeName){
item.cusTypeName = 'N/A';
}
this.record.money += parseFloat(item.money);
});界面显示:

解决方法1(低精度):
在运算结果后调用toFixed()方法,适用于对精度要求不高的场景。
toFixed介绍:
用法: number.toFixed( value )
参数:此函数参数列表包含一个参数,用于指定小数点后保留的精确位数。
返回值:该方法以字符串形式返回一个数字。
代码实现:
res.orderColorDeliveryRecords.forEach((item) => {
item.money = this.actionOperationResult(item.price , item.amount);
if(!item.cusTypeName){
item.cusTypeName = 'N/A';
}
this.record.money += parseFloat(item.money);
});界面显示:

小结:
该方案仅适用于低精度运算场景。如界面显示所示,其弊端在于最终结果会强制去除小数位或保留指定位数。若业务场景不介意小数位的显示方式,此方法仍可使用。
解决方法2(高精度):
先将运算值乘以 10^n 转换为整数进行计算,最后将结果还原。对于精度要求较高的场景,推荐使用此方案。(注:示例代码仅实现了乘法,其他运算需自行调整逻辑)。
代码实现:
actionOperationResult(val1, val2){
const p = this.actionOperation(val1, val2);
return ((val1 * p) * (val2 * p)) / (p * p);
},
actionOperation(val1, val2){
const len1 = val1.toString().length - val1.toString().indexOf(".") - 1;
const len2 = val2.toString().length - val2.toString().indexOf(".") - 1;
const p = Math.max(len1, len2);
// 避免最终求出结果的长度大于最大长度的时候导致精度丢失 开启下面
// p += p - Math.min(len1, len2);
return Math.pow(10, p);
}测试1:
item.money = this.actionOperationResult(item.price , item.amount); 界面显示:

测试2:
const test = this.actionOperationResult(123.456789435252 , 42.697894);
const test1 = this.actionOperationResult(4342.57897 , 64789.337489);
const test2 = this.actionOperationResult(78.7897398 , 67.768978943);
console.log("test:",test);
console.log("test1:",test1);
console.log("test2:",test2);输出结果:

小结:
该方案适用于高精度运算需求。它既解决了精度丢失问题,又满足了最终结果为整数且不显示多余小数位的要求。若对精度有严格要求,请选择此解决方案。
到此这篇关于js运算精度丢失的2个解决方法的文章就介绍到这了,更多相关js运算精度丢失内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!