解决js运算精度丢失问题

问题:

在项目中两值计算时(涉及到浮点数计算),得到的值不是预期的,原因是js运算中精度丢失。

常见案例:

0.1 + 0.2 // 结果为 0.30000000000000004
0.3 - 0.1 // 结果为 0.19999999999999996
0.1 * 0.2 // 结果为 0.020000000000000004
0.3 / 0.1 // 结果为 2.9999999999999996
0.1 + 0.2 === 0.3 // 结果为 false

精度丢失的原因:

因为计算机是采用二进制而不是十进制,所以当十进制的数字转化成二进制则变成了无限不循环的数,但是计算机可支持最大尾数位是52位,所以在模仿十进制的四舍五入后就造成了数据的精度缺失,导致计算错误。

解决方法:

先将运算值 x 10^n 转换成整数进行运算,最后将结果还原

// 计算转换成整数需乘的值
integerOperation(val1, val2){
  // 获取数值1的小数位的长度
  const val1DecimalIndex = val1.toString().indexOf(".");
  const len1 = val1DecimalIndex === -1 ? 0 : val1.toString().length - val1DecimalIndex - 1;
  // 获取数值2的小数位的长度
  const val2DecimalIndex = val2.toString().indexOf(".");
  const len2 = val2DecimalIndex === -1 ? 0 : val2.toString().length - val2DecimalIndex - 1;

  // 获取大的小数位数
  const p = Math.max(len1, len2);
  // 避免最终求出结果的长度大于最大长度的时候导致精度丢失 开启下面
  // p += p - Math.min(len1, len2); 

  // Math.pow() 计算一个数的指定次幂的方法 10的p次方
  return  Math.pow(10, p);
}

// 加法运算
add(val1, val2){
  const p = this.integerOperation(val1, val2);
  return ((val1 * p) + (val2 * p)) / p;
},
// 减法运算
subtract(val1, val2){
  const p = this.integerOperation(val1, val2);
  return ((val1 * p) - (val2 * p)) / p;
},
// 乘法运算
multiply(val1, val2){
  const p = this.integerOperation(val1, val2);
  return ((val1 * p) * (val2 * p)) / (p * p);
},
// 除法运算
multiply(val1, val2){
  const p = this.integerOperation(val1, val2);
  return ((val1 * p) / (val2 * p)) / (p * p);
},

PS:该方案不能解决所有的情况,如特定情况,可以使用专门的高精度数学库,如 Decimal.js、Big.js 或 BigNumber.js 等,以获得更精确的计算结果。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值