Big.js应用
官网链接:big.js API
big.js是一个小巧、快速且易于使用的 JavaScript 库,专门用于任意精度的十进制算术运算。它非常适合处理需要高精度计算的场景,例如金融计算、科学计算等。big.js的设计目标是提供一个简单且高效的 API,使得开发者可以轻松地进行高精度数值计算。
安装
npm install big.js
项目使用 TypeScript版本
npm install big.js npm install @types/big.js -D
PS:
(1)默认传入内容不会类型转换
(2)const num = new Big()无法直接使用,需要使用toString或者toNumber进行转换才能使用
(3)接受的内容不会直接进行转换,比如说null还有undefined,需要额外进行处理。
常用方法
初始化Big number数据
const number = new Big(.1)
// 不推荐 因为不明显
const number = Big(.1)
加减乘除
// 加
const sum = new Big(0.1).plus(0.2);
console.log(sum.toString()); // "0.3"
//--------------------------------------
0.1 + 0.2 // 0.30000000000000004
x = new Big(0.1)
y = x.plus(0.2) // '0.3'
Big(0.7).plus(x).plus(y) // '1.1'
// 减
const difference = new Big(0.3).minus(0.2);
console.log(difference.toString()); // "0.1"
//--------------------------------------
0.3 - 0.1 // 0.19999999999999998
x = new Big(0.3)
x.minus(0.1) // '0.2'
// 乘
const product = new Big(0.1).times(3);
console.log(product.toString()); // "0.3"
//---------------------------------------
0.6 * 3 // 1.7999999999999998
x = new Big(0.6)
y = x.times(3) // '1.8'
// 除
const quotient = new Big(0.3).div(3);
console.log(quotient.toString()); // "0.1"
//----------------------------------------
x = new Big(355)
y = new Big(113)
x.div(y) // '3.14159292035398230088'
Big.DP = 2
x.div(y) // '3.14'
x.div(5) // '71'
从上面可以看到计算误差可以被解决。
保留小数的两种方式
四舍五入(round)
x = 123.45
Math.round(x) // 123
y = new Big(x)
y.round() // '123'
y.round(2) // '123.45'
y.round(10) // '123.45'
y.round(1, Big.roundDown) // '123.4'
y.round(1, Big.roundHalfUp) // '123.5'
y.round(1, Big.roundHalfEven) // '123.4'
y.round(1, Big.roundUp) // '123.5'
y.round(-1, Big.roundDown) // '120'
y.round(-2, Big.roundUp) // '200'
y // '123.45'
保留小数(toFixed)
x = 45.6
y = new Big(x)
x.toFixed() // '46'
y.toFixed() // '45.6'
y.toFixed(0) // '46'
x.toFixed(3) // '45.600'
y.toFixed(3) // '45.600'
转成原始数字类型(toNumber)
x = new Big('123.45')
x.toNumber() // 123.45
y = new Big('1.0000000000000000001')
y.toNumber() // 1
转成String类型(toString)
x = new Big('9.99e+20')
x.toString() // '999000000000000000000'
y = new Big('1E21')
y.toString() // '1e+21'
取绝对值(abs)
x = new Big(-0.8)
x.abs() // '0.8'
相等(eq)
0 === 1e-324 // true
x = new Big(0)
x.eq('1e-324') // false
Big(-0).eq(x) // true ( -0 === 0 )
大于或者大于等于
//大于gt
0.1 > 0.3 - 0.2 // true
x = new Big(0.1)
x.gt(Big(0.3).minus(0.2)) // false
Big(0).gt(x) // false
//大于等于gte
0.3 - 0.2 >= 0.1 // false
x = new Big(0.3).minus(0.2)
x.gte(0.1) // true
Big(1).gte(x) // true
可以看到解决了原先计算不准确问题且,大小判断正确
小于或小于等于
//小于lt
0.3 - 0.2 < 0.1 // true
x = new Big(0.3).minus(0.2)
x.lt(0.1) // false
Big(0).lt(x) // true
//小于等于lte
0.1 <= 0.3 - 0.2 // false
x = new Big(0.1)
x.lte(Big(0.3).minus(0.2)) // true
Big(-1).lte(x) // 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();
}
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 num - 金额
*/
export function transferMoneyToThousand(num?: number | null): string {
if (!num) {
return '0.00';
}
return Big(num)
.toFixed(2) // 保留两位小数
.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
运行结果:transferMoneyToThousand(10000000) // 10,000,000
如果对正则表达式不熟悉的,可以回顾一下之前正则表达式的内容。
正则表达式-CSDN博客
\B表示不在单词的开头或者结尾,是非单词边界。【开头或结尾不出现字符,逗号】
?=n:匹配其后紧接的指定字符串n。 (?=(\d{3})+(?!\d))
\d :查找数字。n{X}:匹配包含X个n的序列的字符串。\d{3} : 查找3个数字
+:重复1次或多次。(\d{3})+ : 3个数字为一组,匹配1次或多次
?!n:匹配其后没有紧接指定字符串n的字符串。(?!\d) :后面没有接单个数字
这里是先行断言。
/\B(?=(\d{3})+(?!\d))/g 整个表达式的意思是,以3个数字为一组匹配,且后面不接单个数字,从后往前匹配,开头结尾不包含字符。
200230405.25.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',')
测试结果:'200,230,405.25'