超好用-js数字相加或相减导致精度丢失溢出的解决方案

前端开发中,不可避免的会用到两个或者多个数据相加或相减的情况,而数字相加或相减,在js中,往往会出现精度丢失的情况。例如:

在这里插入图片描述
我们希望0.1 + 0.2的数值为0.3,但实际上在控制台上输出的却是 0.30000000000000004,这种情况在开发中肯定是要避免的,尤其是在涉及金额计算时,精度丢失就意味着bug的出现。

于是,封装了一个方法,用于解决js中N个数据相加或相减导致的精度丢失,目前该方法只适用于相加或相减,没有封装相乘或相除,如果需要解决相乘相除精度丢失,可以先进行乘除后在使用该方法进行 加 0 或 减 0

// 金额求和(相加/相减)
export const countSum: (arr: number[]) => number = (arr) => {
  if (!arr.length) return 0;
  arr = arr.map((v: number) => {
    if (v && !Number.isNaN(Number(v))) return Math.round(v * 100);
    return 0;
  });
  const result =  arr.reduce((prev: number, curr: number) => {
    return prev + curr
  }, 0);
  return result / 100;
};

使用形式:

  • 相加:countSum( [ a, b, c ] )
  • 相减:countSum( [ a, -b, -c ] )

注意:

  • countSum方法中传入的值必须要是数字,使用该方法前,如果是字符串类型,需要将其转化,最简单的形式是在前面加个 +
  • 如果是金额形式的数字字符串,则很可能包含逗号,在使用该方法前,需要去除其中的逗号,在将其转化成数字,去除数字字符串中的逗号的方法,可以参考我上一篇博客的 get_money_num 方法
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
小数点字符串相减时,为了不丢失精度,可以将字符串转换为高精度的整数,然后进行减法运算,最后再将结果转换回字符串。具体的实现可以采用以下步骤: 1. 将小数点字符串转换为整数数组,例如 "123.456" 转换为 [123, 456]。 2. 判断小数点后面的位数,例如 "123.456" 后面有三位小数。 3. 将整数数组中小数点后面的位数向左移动应的位数,例如 [123, 456] 向左移动 3 位后变为 [123456, 0]。 4. 将整数数组中的每个元素应位置相减,例如 [123456, 0] 减去 [123, 456] 后变为 [123333, -456]。 5. 处理负数,将负数部分向前借位,例如 [123333, -456] 处理后变为 [122877, 544]。 6. 将整数数组转换为字符串,例如 [122877, 544] 转换为 "122877.544"。 代码示例: ```python def sub_float_str(str1, str2): int1, frac1 = map(int, str1.split('.')) int2, frac2 = map(int, str2.split('.')) frac_len = max(len(str(frac1)), len(str(frac2))) frac_scale = 10 ** frac_len int_scale = frac_scale * 10 num1 = int1 * int_scale + frac1 * frac_scale num2 = int2 * int_scale + frac2 * frac_scale diff = num1 - num2 if diff < 0: sign = '-' diff = -diff else: sign = '' int_diff, frac_diff = divmod(diff, frac_scale) int_diff_str = str(int_diff) frac_diff_str = str(frac_diff).rjust(frac_len, '0') res = sign + int_diff_str + '.' + frac_diff_str return res ``` 这个函数可以计算两个小数点字符串的差值,并返回一个字符串,保证了精度丢失。例如: ```python >>> sub_float_str('123.456', '78.9') '44.556' ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值