安装
# pnpm
pnpm add big.js
# yarn
yarn add big.js
# npm
npm install big.js
项目使用 TypeScript版本
# pnpm
pnpm add big.js
pnpm add @types/big.js -D
# yarn
yarn add big.js
yarn add @types/big.js -D
# npm
npm install big.js
npm install @types/big.js -D
注意
1、默认传入内容不会类型转换
2、const num = new Big() 无法直接使用 需要使用 toString 或者 toNumber 进行转换才能使用
3、接受的内容 不会直接进行转化 比如说 null 还有 undefine,需要额外进行处理
使用
import Big from 'big.js'
相关方法
初始化Big number数据
const number = new Big(.1)
// 不推荐 因为不明显
const number = Big(.1)
加减法(plus | minus)
// 加
const sum = new Big(0.1).plus(0.2);
console.log(sum.toString()); // "0.3"
// 减
const difference = new Big(0.3).minus(0.2);
console.log(difference.toString()); // "0.1"
乘除法运算(times | div)
// 乘
const product = new Big(0.1).times(3);
console.log(product.toString()); // "0.3"
// 除
const quotient = new Big(0.3).div(3);
console.log(quotient.toString()); // "0.1"
取整(round)
- 可以进行四舍五入
const num1 = new Big(1.235);
console.log(num1.round(2).toString()); // "1.24" (保留两位小数,四舍五入)
console.log(num1.round(2, 1).toString()); // "1.23" (向下取整)
console.log(num1.round(2, 2).toString()); // "1.24" (向上取整)
console.log(num1.round(2, 3).toString()); // "1.23" (截断)
取整toFixed()
- 不进行四舍五入
const result = new Big(1.23456).toFixed(2);
console.log(result); // "1.23"
转化成 number(toNumber)
- 返回 JavaScript 原生数字类型
- 可能因浮点数限制导致精度损失不适合高精度场景
const num = new Big(0.1).plus(0.2); // 0.1 + 0.2
console.log(num.toNumber()); // 0.3
转化成 string(toString)
- 完全保留精度
- 数据展示、存储高精度值
const num = new Big(0.1).plus(0.2); // 0.1 + 0.2
console.log(num.toString()); // "0.3"
取绝对值(abs)
const num1 = new Big(-0.999);
console.log(num1.abs()); // Big2 {s: 1, e: -1, c: Array(3)}
console.log(num1.abs().toNumber()); // '0.999'
console.log(Number(num1.abs())); // '0.999'
相等(eq)
const isEqual = new Big(0.3).eq(0.1 + 0.2); // 注意:0.1 + 0.2 是浮点数计算,有误差
console.log(isEqual); // false
const isEqualFixed = new Big(0.3).eq(new Big(0.1).plus(0.2));
console.log(isEqualFixed); // true
大于或者大于等于
// gt (大于)
console.log(0.1 > 0.3 - 0.2); // true
// 原因:0.3 - 0.2 的结果是 0.09999999999999998,0.1 > 0.09999999999999998
console.log(new Big(0.1).gt(new Big(0.1).minus(0.2))); // false
// 原因:Big.js 精确计算,0.1 > (0.1 - 0.2),即 0.1 > -0.1,结果为 false
---------------------------------------------------------------------------------
// gte (大于等于)
console.log(0.3 - 0.2 <= 0.1); // true
// 原因:0.09999999999999998 <= 0.1,结果为 true
console.log(new Big(0.1).gte(new Big(0.3).minus(0.2))); // true
// 原因:Big.js 精确计算,0.1 >= (0.3 - 0.2),即 0.1 >= 0.1,结果为 true
小于或小于等于
// lt (小于)
console.log(0.1 < 0.3 - 0.2); // false
// 原因:0.1 < 0.09999999999999998,结果为 false
console.log(new Big(0.1).lt(new Big(0.3).minus(0.2))); // true
// 原因:Big.js 精确计算,0.1 < (0.3 - 0.2),即 0.1 < 0.1,结果为 true
---------------------------------------------------------------------------------
// lte (小于等于)
console.log(0.3 - 0.2 <= 0.1); // true
// 原因:0.09999999999999998 <= 0.1,结果为 true
console.log(new Big(0.1).lte(new Big(0.3).minus(0.2))); // true
// 原因:Big.js 精确计算,0.1 <= (0.3 - 0.2),即 0.1 <= 0.1,结果为 true
业务封装使用
/**
* 格式化数值 乘以100
* @param value number
* @returns number * 100
*/
export function formatTimes100(value: number) {
if (!isNumber(value)) {
return null;
}
return new Big(value).times(100).toNumber();
}
/**
* 格式化数值 除以100
* @param value number
* @returns number / 100
*/
export function formatDiv100(value: number) {
if (!isNumber(value)) {
return null;
}
return new Big(value).div(100).round(4).toNumber();
}
两数相除
/**
* @param x number | null | string
* @param y number | null | string
* @returns x / y bao
*/
function itemDiv(x, y) {
try {
return new Big(x || 0)
.div(new Big(y) || 0)
.round(2)
.toNumber();
} catch (error) {
return 0;
}
}
通用计算
import Big from "big.js";
/**
* 通用合计计算函数
* @param dataList 数据数组
* @param field 字段名称,用于提取需要计算的数值
* @param filterFn 可选的过滤函数,返回 true 的项将被计入合计
* @param decimalPlaces 小数位保留数,默认保留两位小数
* @returns 合计结果,保留指定小数位
*/
function calculateTotal(
dataList: Array<Record<string, any>>,
field: string,
filterFn?: (item: Record<string, any>) => boolean,
decimalPlaces: number = 2
): string {
const total = dataList.reduce((current, item) => {
// 如果有过滤函数,先进行过滤判断
if (filterFn && !filterFn(item)) {
return current;
}
// 累加指定字段的值,默认值为 0
return current.plus(new Big(item[field] || 0));
}, new Big(0));
// 返回结果,保留指定小数位数
return total.round(decimalPlaces).toString() || "0.00";
}
----------------------------------------------------------------------
// 简单合计
const data = [
{ value: 10 },
{ value: 20 },
{ value: 30 },
];
const total = calculateTotal(data, "value");
console.log(total); // "60.00"
----------------------------------------------------------------------
// 带过滤条件的合计
const data = [
{ selectionStatus: true, value: 10 },
{ selectionStatus: false, value: 20 },
{ selectionStatus: true, value: 30 },
];
const total = calculateTotal(
data,
"value",
(item) => item.selectionStatus // 仅计算 selectionStatus 为 true 的项
);
console.log(total); // "40.00"
----------------------------------------------------------------------
// 自定义小数位
const data = [
{ value: 10.123 },
{ value: 20.456 },
{ value: 30.789 },
];
const total = calculateTotal(data, "value", undefined, 1); // 保留 1 位小数
console.log(total); // "61.4"
----------------------------------------------------------------------
const data = [
{ value: 10 },
{ value: null },
{ value: undefined },
{ value: 20 },
];
const total = calculateTotal(data, "value");
console.log(total); // "30.00"