小数相加丢失精度的问题解决

本文介绍了在Vue3项目中遇到的精度丢失问题,通过引入bignumber.js库来解决小数和整数计算时的精度问题,提供了处理数组数据和执行加、减、乘、除等操作的方法。
摘要由CSDN通过智能技术生成

🔮 欢迎点赞 👍٩( ´︶` )( ´︶` )۶ 收藏 🌟留言 💌 欢迎讨论!💕
🔮 本文由 【第四人称Alice】 原创,首发于 CSDN ✨✨✨
🌍 由于博主还属于前期的前端开发小白,欢迎大家留言提出更好的意见,大家共同进步!💭

声明:博主的项目是vue3+ts

项目中有的时候写一些需要计算金额的时候总会出现精度丢失问题

1、安装

npm install bignumber.js --save

2、引入

import BigNumber from 'bignumber.js'

3、使用

// 小数和整数相加
let testArr1 = reactive<numArr[]>([
  { id: 1, num: 2 },
  { id: 2, num: 2.23 },
  { id: 3, num: 2.25 },
])
let testArr2 = reactive<(string | number)[]>([5.781, '3.231', 4.261])
/**
 *  目前只写了处理一层数据的函数,后续再研究一下多层数据的处理
 * @param data   被处理数据
 * @param attribute 如果是对象,则需要传入的属性
 * @param length   保留几位小数
 */
const addArr = (data: any[], attribute?: string, length?: number) => {
  let typeJudgment = data.every((element) => typeof element === 'object' && element !== null && !Array.isArray(element))
  let addRes = data.reduce((pre: any, cur: any) => {
    const valueToOperateOn = typeJudgment ? new BigNumber(cur[attribute as string]) : new BigNumber(cur)
    return pre.plus(valueToOperateOn)
  }, new BigNumber(0))
  let res =
    addRes.c.length > 1
      ? Number(addRes.c[0] + "." + String(addRes.c[1]).slice(0, length))
      : Number(addRes.c[0]);
  return res;
}
console.log(addArr(testArr1, 'num', 2)) //6.48
console.log(addArr(testArr2, 'num', 3)) //13.273

4、综合用法

/**
 *
 * @param data   被计算的数据
 * @param init   初始值
 * @param type   计算类型:1.加、2.减、3.乘、4.除
 * @param length 保留小数位数
 * @param attribute 被计算属性
 */
const calculateData = (data: any[], init: number, type: number, length?: number, attribute?: string) => {
  let typeJudgment = data.every((element) => typeof element === 'object' && element !== null && !Array.isArray(element))

  let initial = new BigNumber(init)

  data.forEach((v) => {
    const valueToOperateOn = typeJudgment ? new BigNumber(v[attribute as string]) : new BigNumber(v)
    switch (type) {
      case 1:
        initial = initial.plus(valueToOperateOn)
        break
      case 2:
        initial = initial.minus(valueToOperateOn)
        break
      case 3:
        initial = initial.times(valueToOperateOn)
        break
      case 4:
        initial = initial.div(valueToOperateOn)
        break
      default:
        throw new Error(`Unsupported operation type: ${type}`)
    }
  })

  let res =
    addRes.c.length > 1
      ? Number(addRes.c[0] + "." + String(addRes.c[1]).slice(0, length))
      : Number(addRes.c[0]);
  return res;
}
console.log(calculateData(testArr2, 0, 1, 3)) //13.273
console.log(calculateData(testArr1, 20, 2, 2, 'num')) //13.52

5、其他更多使用方法可参考官方参考地址

文档地址(英文):bignumber.js API

项目地址:GitCode - 开发者的代码家园

npm地址:bignumber.js - npm

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值