js中加减乘除,部分数据会存在计算不准确。
我使用的是big.js,基于big.js库封装了下工具方法,当然也可以用其他库,如mathjs
/bignumber.js
。
numberMultiply(0.2, 0.7) // 0.14 乘法
numberMultiply(0.2, ‘0.7’) // 0.14 可以是字符串类型的数字
numberMultiply(0.2, 0.7, 4, false) // ‘0.1400’
numberDiv(5, 2) // 2.5 除法
numberPlus(5, 2) // 7 加法
numberMinus(5, 2) // 3 减法
// 四舍五入
numberToFixed(12.225, 2) // 12.23
numberToFixed(12.225, 4, false) // ‘12.2250’
代码&使用示例:
numberUtil.ts
/**
* @fileOverview 数值计算工具类
* @date 2024-5-30
*/
import Big from 'big.js';
/**
* 四舍五入
* @param number 数字
* @param precision 精度,不传则默认保留两位小数
* @param isReturnNumber 是否返回数字类型,默认返回数字类型,否则返回字符串类型
*/
export function numberToFixed(number: number | string, precision = 2, isReturnNumber = true) {
try {
const bigNum = new Big(number).round(precision);
// 直接返回数字类型
if (isReturnNumber) return bigNum.toNumber().valueOf();
// 返回字符串类型,不足位数用0补齐
return bigNum.toFixed(precision).valueOf();
} catch (e) {
return '';
}
}
type numberComputeType = 'times' | 'div' | 'plus' | 'minus';
/**
* 数值计算
* @param type
* @param number1 数值1
* @param number2 数值2
* @param precision 精度,不传不处理精度
* @param isReturnNumber 是否返回数字类型,默认返回数字类型,否则返回字符串类型
*/
function numberCompute(
type: numberComputeType,
number1: number | string,
number2: number | string,
precision: number | undefined,
isReturnNumber: boolean | undefined
) {
try {
const bigNum = new Big(number1)[type](number2);
const value = bigNum.toNumber().valueOf();
if (precision === 0 || precision) return numberToFixed(value, precision, isReturnNumber);
return value;
} catch (e) {
return '';
}
}
/**
* 数值计算
* @params [数值1, 数值2, 精度?, 是否返回数字类型?]
*/
type numberComputeArgs = [string | number, string | number, number?, boolean?];
/**
* 乘法
* @param args 数值1, 数值2, 精度?, 是否返回数字类型?
*/
export const numberMultiply = (...args: numberComputeArgs) => numberCompute('times', ...args);
/**
* 除法
* @param args 数值1, 数值2, 精度?, 是否返回数字类型?
*/
export const numberDiv = (...args: numberComputeArgs) => numberCompute('div', ...args);
/**
* 加法
* @param args 数值1, 数值2, 精度?, 是否返回数字类型?
*/
export const numberPlus = (...args: numberComputeArgs) => numberCompute('plus', ...args);
/**
* 减法
* @param args 数值1, 数值2, 精度?, 是否返回数字类型?
*/
export const numberMinus = (...args: numberComputeArgs) => numberCompute('minus', ...args);
代码&使用示例:
// MyBig方法,创建Big实例
function MyBig(x) {
try {
this.value = x instanceof MyBig ? x.value : new Big(x);
} catch (e) {
console.error("MyBig-error", e);
this.value = new Big(0);
}
}
// 四舍五入 round
MyBig.prototype.round = function (precision = 2) {
this.precision = precision;
this.value = this.value.round(precision);
return this;
};
// 计算方法
function computedNumber(type) {
return function (n, precision) {
this.value = this.value[type](n);
// 如果传入精度了,则进行四舍五入
if (precision && precision !== 0) {
this.round(precision);
}
return this;
};
}
// 定义MyBig内要使用的方法
const computedTypes = {
add: "add", // 加法 add
sub: "sub", // 减法 sub
div: "div", // 除法 div
times: "times", // 乘法 times
};
Object.keys(computedTypes).forEach((key) => {
MyBig.prototype[key] = computedNumber(computedTypes[key]);
});
// 使用方法
// 使用 new MyBig()创建MyBig示例
const d1 = new MyBig(12.225); // 创建实例
d1.round(); // 进行四舍五入 12.23
d1.add(0.27); // 加法 12.5
d1.sub(2.5); // 减法 10
d1.times(2); // 乘法 20
d1.div(4); // 乘法 5
d1.valueOf(); // 获取结果值
// 链式调用写法:
const d2 = new MyBig(12.225).round().add(0.27).sub(2.5).times(2).div(4).valueOf(); // 5
// d1.value可直接调用 Big.js方法,该操作不会修改d1的值
d1.value.div(2);
// 计算数值的同时进行四舍五入计算
const d3 = new MyBig(0.1225); // 创建实例
console.log(d3.add(0.1225, 2).valueOf()) // 0.25