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