首页 > 编程语言 >关于javaScript的计算精度的解决办法

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

时间:2024-03-22 18:00:49浏览次数:31  
标签:解决办法 return comp javaScript num Math 计算精度 math const

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

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;

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

标签:解决办法,return,comp,javaScript,num,Math,计算精度,math,const
From: https://blog.csdn.net/weixin_54205973/article/details/136900873

相关文章

  • vue或react项目上线刷新出现404的原因以及解决办法
    问题描述:vue/react项目,正常的页面操作跳转,不会出现404的问题,但是一旦刷新,就会出现404报错。产生原因:我们打开vue/react打包后生成的dist文件夹,可以看到只有一个index.html文件及一些静态资源,这个是因为vue/react是单页应用(SPA),只有一个index.html作为入口文件,其它的路由都是通......
  • JavaScript object.is()和严格相等、非严格相等的区别
    1.==(相等运算符)        当使用==比较两个值时,如果它们的类型不同,JavaScript会尝试将它们转换为一个共同的类型,然后再进行比较。这个过程称为类型转换或类型强制。0=='0'//true,因为字符串'0'会转换为数字01==true//true,因为布尔值true会转换为数字1nul......
  • JavaScript 本地存储
    1.前言由来:localStorage和sessionStorage是HTML5标准中新加入的技术,用于保存整个网站的数据两者区别:localStorage的生命周期是永久的,除非手动删除,而sessionStorage仅在当前会话下有效(即使是同个域名下的网页也无法访问当前会话下创建的键值对,关闭页面或浏览器后被清除,刷新当......
  • JavaScript 权威指南第七版(GPT 重译)(三)
    第六章:对象对象是JavaScript中最基本的数据类型,您在本章之前的章节中已经多次看到它们。因为对象对于JavaScript语言非常重要,所以您需要详细了解它们的工作原理,而本章提供了这些细节。它从对象的正式概述开始,然后深入到关于创建对象和查询、设置、删除、测试和枚举对象属性的......
  • JavaScript 权威指南第七版(GPT 重译)(四)
    第九章:类JavaScript对象在第六章中有所涉及。该章将每个对象视为一组独特的属性,与其他对象不同。然而,通常有必要定义一种共享某些属性的对象类。类的成员或实例具有自己的属性来保存或定义它们的状态,但它们还具有定义其行为的方法。这些方法由类定义,并由所有实例共享。例如,想象......
  • JavaScript 权威指南第七版(GPT 重译)(五)
    第十二章:迭代器和生成器可迭代对象及其相关的迭代器是ES6的一个特性,在本书中我们已经多次见到。数组(包括TypedArrays)、字符串以及Set和Map对象都是可迭代的。这意味着这些数据结构的内容可以被迭代——使用for/of循环遍历,就像我们在§5.4.4中看到的那样:letsum=0;for......
  • JavaScript 权威指南第七版(GPT 重译)(一)
    前言本书涵盖了JavaScript语言以及Web浏览器和Node实现的JavaScriptAPI。我为一些具有先前编程经验的读者编写了这本书,他们想要学习JavaScript,也为已经使用JavaScript的程序员编写了这本书,但希望将他们的理解提升到一个新的水平,并真正掌握这门语言。我写这本书的目标......
  • JavaScript 权威指南第七版(GPT 重译)(二)
    第四章:表达式和运算符本章记录了JavaScript表达式以及构建许多这些表达式的运算符。表达式是JavaScript的短语,可以评估以产生一个值。在程序中直接嵌入的常量是一种非常简单的表达式。变量名也是一个简单表达式,它评估为分配给该变量的任何值。复杂表达式是由简单表达式构......
  • 详细解读JavaScript中的防抖(debounce)和节流(throttle)!!!
    在JavaScript中,防抖(debounce)和节流(throttle)是两种常用的技术,用于限制函数的执行频率,特别是在处理高频事件(如窗口的resize、scroll,输入框的keyup、mousedown等)时非常有用。防抖(debounce)防抖的基本思想是将多次执行变为最后一次执行。也就是说,在事件被触发后n秒内函数只能执......
  • JavaScript 中对象的浅拷贝(Shallow Copy)和深拷贝(Deep Copy)!!
    在JavaScript中,对象的拷贝可以分为浅拷贝(ShallowCopy)和深拷贝(DeepCopy)。理解这两者的区别是非常重要的,因为它们影响着拷贝后的对象与原始对象之间的关系。浅拷贝(ShallowCopy):浅拷贝只会拷贝对象的第一层属性。如果对象的属性是基本数据类型(例如,字符串,数字,布尔值等),那......