关于javaScript的计算精度的解决办法

文章介绍了在JavaScript项目中处理浮点数计算精度问题的三种方法:自定义封装函数、使用math.js插件(v2和nuxt3版本)以及处理科学计数法。作者提供了示例代码并强调了注意事项和适用场景的调整。
摘要由CSDN通过智能技术生成

项目中我们常常需要做一些计算,由于浮点数的二进制表示可能不精确,经常会遇到计算精度问题,例

let resultNum=0.1+0.2;
console.log(resultNum);//0.30000000000000004

这个时候,如果我们不单独处理,那么页面上展示的时候就出现布局错乱等问题,比如我们可以保留两位小数采用Number(resultNum).toFixed(2),但是部分时候精度又达不到我们的要求。所以以下我做了几种解决计算的方法,亲测有效

一、自己封装方法,不采用插件

我们采用获取浮点的长度,拿到两个值最长的长度,通过设置10的幂次方,去掉浮点,计算后再除与对应的幂次方,来保证运算过程中不存在浮点,最后还需要处理科学计数法,不然就会出现一下结果。

let result=math.multiply(2,5000000);
console.log(result);//4e-7
// 使用这些方法,仍然需要注意数值范围、舍入策略和比较运算等方面的问题,根据具体的应用场景进行适当的调整和处理。
const math = {
    // 加法运算
    add: function (a, b) {
        const precision = Math.max(getPrecision(a), getPrecision(b));
        const multiplier = Math.pow(10, precision);
        const result=(Math.round(a * multiplier) + Math.round(b * multiplier)) / multiplier;
        return transferToNumber(result)
    },

    // 减法运算
    subtract: function (a, b) {
        return transferToNumber(math.add(a, -b));
    },

    // 乘法运算
    multiply: function (a, b) {
        const precision = getPrecision(a) + getPrecision(b);
        const multiplier = Math.pow(10, precision);
        const result=(Math.round(a * multiplier) * Math.round(b * multiplier)) / (multiplier * multiplier);
        return transferToNumber(result)
    },

    // 除法运算
    divide: function (num1, num2) {
        var str1 = Number(num1).toString(),
            str2 = Number(num2).toString(),
            result,
            str1Length,
            str2Length;
        //解决整数没有小数点方法
        try {
            str1Length = str1.split(".")[1].length;
        } catch (error) {
            str1Length = 0;
        }
        try {
            str2Length = str2.split(".")[1].length;
        } catch (error) {
            str2Length = 0;
        }
        var step = Math.pow(10, Math.max(str1Length, str2Length));
        result = (num1 * step) / (num2 * step);
        return transferToNumber(result);
    },

    // 获取浮点数的小数位数
};
function getPrecision(num) {
    const str = String(num);
    const decimalIndex = str.indexOf(".");
    return decimalIndex === -1 ? 0 : str.length - decimalIndex - 1;
}
// 处理出现科学计数法
function transferToNumber(num) {
    if (isNaN(num)) {
      return num
    }
    num = '' + num
    num = parseFloat(num)
    let eformat = num.toExponential() // 转换为标准的科学计数法形式(字符串)
    let tmpArray = eformat.match(/\d(?:\.(\d*))?e([+-]\d+)/) // 分离出小数值和指数值
    let number = num.toFixed(Math.max(0, (tmpArray[1] || '').length - tmpArray[2]))
    return number 
}
export default math;

二、使用插件,在v2中使用

        插件使用的math.js,需要下载对应的依赖包  npm install mathjs

let $math = require('mathjs');
const math = {
   //加法
  add() {
    return comp('add', arguments)
  },
   //减法
  subtract() {
    return comp('subtract', arguments)
  },
    // 乘法
  multiply() {
    return comp('multiply', arguments)
  },
   // 除法
  divide() {
    return comp('divide', arguments)
  },
}
function comp(_func, args) {
  let t = $math.chain($math.bignumber(args[0]));
  for (let i=1; i<args.length; i++) {
    t = t[_func]($math.bignumber(args[i]))
  }
  // 防止超过6位使用科学计数法
  return parseFloat(t.done())
}
export default math;

  三、使用插件,在nuxt3中使用

        插件使用的math.js,需要下载对应的依赖包  npm install mathjs

        这里采用v2的封装方式不可行,所以这里是单独做了一个处理

import { create, all } from "mathjs";
const config = {
  number: "BigNumber",
  precision: 20,
};
const $math = create(all, config);

const math = {
  //加法
  add() {
    return comp("add", arguments);
  },
  //减法
  subtract() {
    return comp("subtract", arguments);
  },
  // 乘法
  multiply() {
    return comp("multiply", arguments);
  },
  // 除法
  divide() {
    return comp("divide", arguments);
  },
};

function comp(_func, args) {
  let t = $math.chain($math.bignumber(args[0]));
  for (let i = 1; i < args.length; i++) {
    t = t[_func]($math.bignumber(args[i]));
  }
  // 防止超过6位使用科学计数法
  return parseFloat(t.done());
}
export default math;

        以上是在完成项目中遇到计算的精度问题的个人处理方法,本人亲测没有什么问题,大家也可以是试试,不足之处恳请各位大佬批评指正,谢谢!!!

  • 19
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Vue中解决JavaScript计算精度问题,可以使用第三方库math.js。通过引入math.js库,我们可以避免在浮点数计算中出现的精度问题。 在Vue中使用math.js可以按照以下步骤进行: 1. 首先,安装math.js库。可以使用npm或者yarn进行安装,例如:`npm install mathjs`。 2. 在Vue组件中引入math.js库,可以使用import语句进行引入,例如:`import math from 'mathjs'`。 3. 在需要进行计算的地方,使用math.js提供的相应方法进行计算。例如,对于减法,可以使用`math.subtract()`方法,对于加法,可以使用`math.add()`方法,对于除法,可以使用`math.divide()`方法。 4. 由于math.js处理的是大整数和大浮点数,所以在进行计算之前,需要将需要计算的数字转换成math.js支持的格式。可以使用`math.bignumber()`方法将数字转换成math.js支持的格式。 5. 最后,使用`math.format()`方法将计算结果转换成字符串格式,以避免出现科学计数法或多余的小数位。 举例来说,如果要解决0.1 + 0.2的计算精度问题,可以按照以下代码进行操作: ```javascript import math from 'mathjs' const addNumber = math.format(math.add(math.bignumber(0.1), math.bignumber(0.2))) console.log(addNumber) // 输出0.3 ``` 使用类似的方法,可以解决减法和除法的计算精度问题。请记住,在进行计算之前,将需要计算的数字转换成math.js支持的格式,然后使用相应的数学方法进行计算,并最后使用`math.format()`方法转换结果。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [vue使用mathjs解决前端计算精度不足问题](https://blog.csdn.net/qq_43555948/article/details/119885043)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值