JavaScript数字运算必备库 ——— big.js
big.js 是一个方便易用的 npm 包, 复制JavaScript数字的toExponential、toFixed和toPrecision方法, 可以用于精确计算大数值。本文介绍了 big.js 的基本用法和设置精度的方法,如何在项目中引用 big.js 计算
安装
script 标签嵌入
<script src="https://cdn.bootcdn.net/ajax/libs/big.js/6.2.1/big.min.js"></script>
npm 或 yarn 安装
npm install big.js
yarn add big.js
CommonJS
const Big = require('big.js');
ES module:
import Big from 'big.js';
big.js的API主要分为以下两个部分:
常量定义
-
DP 小数点后位数,默认值是20
-
数字:整数,0到1e+6(含)
-
默认值:20
-
涉及除法的运算结果的最大小数位数
-
它只与div和sqrt方法相关,当指数为负时,它与pow方法相关。
Big.DP = 40
当调用上述方法之一时,将检查该值的有效性。如果发现该值无效,将引发错误。
-
-
RM 四舍五入方式,默认为1,代表向最近的整数取整。如果是0.5,那么向下取整。
-
数字 : 0, 1, 2 or 3
-
默认值: 1
-
在涉及除法和按舍入、到Exponential、到Fixed和到Precision的操作中使用的舍入模式。
Big.RM = 0 Big.RM = Big.roundUp
当调用上述方法之一时,将检查该值的有效性。如果发现该值无效,将引发错误。
-
-
NE 在转换为字符串时展示为科学计数法的最小小数位数。默认值是-7,即小数点后第7为才开始不是0。
-
数字: 整数, -1e+6 to 0 (含)
-
默认值: -7
-
toString返回指数表示法的负指数值。
Big.NE = -7 x = new Big(0.00000123) // '0.00000123' e is -6 x = new Big(0.000000123) // '1.23e-7'
JavaScript数字对-7及以下的负指数使用指数表示法。
无论Big.NE的值是多少,toFixed方法都将始终以正常表示法返回值,而toExponential方法将始终以指数形式返回值。
-
-
PE 在转换为字符串时展示位科学计数法的最小整数位数。默认值是21,即数字长度超过21位。
-
数字: 整数,0 到 1e+6 (含)
-
默认值: 21
-
toString返回指数表示法的正指数值。
Big.PE = 2 x = new Big(12.3) // '12.3' e is 1 x = new Big(123) // '1.23e+2'
JavaScript数字使用指数表示法表示21及以上的正指数。
无论Big.PE的值如何,toFixed方法都将始终以正常表示法返回值,而toExponential方法将始终以指数形式返回值。
-
-
strict 默认值为false。设置为true时,构造函数只接受字符串和大数
-
数字 : 整数,0 到 1e+6 (含)
-
默认值:21
-
当设置为true时,如果将基元数传递给Big构造函数,或者调用valueOf,或者在Big上调用toNumber,则将引发错误,而Big无法在不损失精度的情况下转换为基元数。
Big.strict = true x = new Big(1) // 'TypeError: [big.js] String expected' y = new Big('1.000000000000000000001') 2 + y // 'Error: [big.js] valueOf disallowed' y.toNumber() // 'Error: [big.js] Imprecise conversion' Big.strict = false x = new Big(0.1) y = new Big('1.000000000000000000001') 2 + y // '21.000000000000000000001' y.toNumber() // 1
-
运算符操作函数
使用 运算符操作函数 计算后的结果是个
big
对象,所以需要转换成number类型,可以使用.toNumber()
或者Number()
转为number类型, 由于计算结果是big
对象,可以使用链式调用进行复杂计算
-
abs()
,取绝对值。let num = new Big(-0.666) console.log(num.abs()); // f {s: 1, e: -1, c: Array(3), constructor: ƒ} console.log(num.abs().toNumber()); // '0.666' console.log(Number(num.abs())); // '0.666'
-
cmp()
,compare的缩写,即比较函数。let num1 = new Big(11); let num2 = new Big(22); console.log(num1.cmp(num2)); // -1 console.log(num2.cmp(num1)); // 1 console.log(num1.cmp(num2.minus(11))); // 0
-
div()
,除法。let num3 = new Big(666); let num4 = new Big(3); console.log(Number(num3.div(num4))); // 222
-
eq()
,equal的缩写,即相等比较。let num5 = new Big(0); let num6 = new Big('1e-324'); let num7 = new Big(-0); console.log(0 === Number('1e-324')); // true console.log(num5.eq(num4)); // false console.log(num7.eq(num5)); // true
-
gt()
,大于。let num8 = new Big(0.1); let num9 = new Big(0.3); console.log(0.1 > 0.3 - 0.2); // true 小数点计算会有精度丢失 0.3 -0.2 结果 是 0.09999999999999998 所以为true console.log(num8.gt(num9.minus(0.2))); // false
-
gte()
,小于等于,e表示equal。let num10 = new Big(0.1); let num11 = new Big(0.3); console.log(0.3 - 0.2 <= 0.1); // true console.log(num10.gte(num11.minus(0.2))); // true
-
lt()
,小于。let num12 = new Big(0.1); let num13 = new Big(0.3); console.log(0.3 - 0.2 < 0.1); // true console.log(num12.lt(num13.minus(0.2))); // false
-
lte()
,小于等于,e表示equal。let num14 = new Big(0.1); let num15 = new Big(0.3); console.log(0.3 - 0.2 <= 0.1); // true console.log(num14.gte(num15.minus(0.2))); // true
-
minus()
,减法。let num16 = new Big(0.1); let num17 = new Big(0.3); console.log(num17.minus(num16).toNumber()); // 0.2
-
mod()
,取余。let num18 = new Big(0.3); let num19 = new Big(1); console.log(1 % 0.3); // 0.10000000000000003 console.log(num19.mod(num18).toNumber()); // 0.1
-
neg()
,取反。let num20 = new Big(0.3); console.log(num20.neg().toNumber()); // -0.3 console.log(num20.neg().neg().toNumber()); // 0.3
-
plus()
,加法。let num21 = new Big(0.1); let num22 = new Big(0.2); console.log(0.1 + 0.2); // 0.30000000000000004 console.log(num21.plus(num22).toNumber()); // 0.3
-
pow()
,次方。let num23 = new Big(0.2); let num24 = new Big(3); console.log(Math.pow(0.2, 2)); // 0.04000000000000001 console.log(num23.pow(2).toNumber()); // 0.04 console.log(num24.pow(-2).toNumber()); // 0.1111111111111111
-
prec()
,按精度舍入,参数表示整体位数。let num25 = new Big(98765.4321); let down = 0; let half_up = 1; console.log(num25.prec(5).toNumber()); // 98765 console.log(num25.prec(2).toNumber()); // 99000 console.log(num25.prec(10).toNumber()); // 98765.4321 console.log(num25.prec(1, down).toNumber()); // 90000 console.log(num25.prec(1, half_up).toNumber()); // 100000
-
round()
,按精度舍入,参数表示小数点后位数。let num26 = new Big(98765.4321); console.log(Math.round(98765.4321)); // 98765 console.log(num26.round().toNumber()); // 98765 console.log(num26.round(2).toNumber()); // 98765.43 console.log(num26.round(10).toNumber()); // 98765.4321 console.log(num26.round(1, Big.roundDown).toNumber()); // 98765.4 console.log(num26.round(1, Big.roundHalfUp).toNumber()); // 98765.4 console.log(num26.round(1, Big.roundHalfEven).toNumber()); // 98765.4 console.log(num26.round(1, Big.roundUp).toNumber()); // 98765.5 console.log(num26.round(-1, Big.roundDown).toNumber()); // 98760 console.log(num26.round(-2, Big.roundUp).toNumber()); // 98800
-
sqrt()
,开方。let num27 = new Big(0.04); let num28 = new Big(3); console.log(num27.sqrt().toNumber()); // 0.2 console.log(num28.sqrt().toNumber()); // 1.7320508075688772
-
times()
,乘法。let num29 = new Big(0.1); let num30 = new Big(0.2); console.log(num29.times(num30).toNumber()); // 0.02
-
toExponential()
,转化为科学计数法,参数代表精度位数。let num31 = 11; let num32 = new Big(num31); console.log(num31.toExponential()); // 1.1e+1 console.log(num32.toExponential()); // 1.1e+1 console.log(num31.toExponential(0)); // 1e+1 console.log(num32.toExponential(0)); // 1e+1 console.log(num31.toExponential(1)); // 1.1e+1 console.log(num32.toExponential(1)); // 1.1e+1 console.log(num32.toExponential(1, Big.roundDown)); // 1.1e+1 console.log(num31.toExponential(3)); // 1.100e+1 console.log(num32.toExponential(3)); // 1.100e+1
-
toFixed()
,四舍五入 。javaScript 的 toFixed() 方法也可把 Number 四舍五入为指定小数位数的数字。例如将数据Num保留2位小数,则表示为:toFixed(Num);但是其四舍五入的规则与数学中的规则不同,使用的是银行家舍入规则,银行家舍入:所谓银行家舍入法,其实质是一种四舍六入五取偶(又称四舍六入五留双)法。
具体规则如下:
简单来说就是:四舍六入五考虑,五后非零就进一,五后为零看奇偶,五前为偶应舍去,五前为奇要进一。
let num33 = 3.1445; let num34 = 3.1455; let num35 = new Big(num33); console.log(num33.toFixed(3)); // 3.144 console.log(num34.toFixed(3)); // 3.146 console.log(num35.toFixed(3)); // 3.145
-
toJSON()
和toString()
,转化为字符串。let str1 = new Big('177.7e+457'); let str2 = new Big(1234.5678); let str3= new Big('0.987654321'); console.log(str1.toJSON()); // 1.777e+459 console.log(str2.toJSON()); // 1234.5678 console.log(str3.toJSON()); // 0.987654321 console.log(str1.toString()); // 1.777e+459 console.log(str2.toString()); // 1234.5678 console.log(str3.toString()); // 0.987654321
-
toPrecision()
,按指定有效位数展示,参数为有效位数。let num36 = 123.456; let num37 = new Big(num36); console.log(num36.toPrecision()); // 123.456 console.log(num37.toPrecision()); // 123.456 console.log(num36.toPrecision(1)); // 1e+2 console.log(num37.toPrecision(1)); // 1e+2 console.log(num36.toPrecision(5)); // 123.46 console.log(num37.toPrecision(5)); // 123.46
-
toNumber()
,转化为JavaScript中number类型。let num38 = new Big('123.456'); let num39 = new Big('1.0000000000000000001') console.log(num38.toNumber()); // 123.456 console.log(num39.toNumber()); // 1
-
valueOf()
,包含负号(如果为负数或者-0)的字符串。let num40 = new Big('-123.456'); let num41 = new Big('-0'); console.log(num40.valueOf()); // -123.456 console.log(num41.valueOf()); // -0 console.log(num41.toString()); // 0
详情请查看文档 big.js
在vue项目中使用
- 安装big.js
npm i big.js
yarn add big.js
- 在main.js 中引入
import App from "./App";
import store from "./store";
import router from "./router";
import Vue from "vue";
import Big from 'big.js';
// 将Big挂载为Vue的原型属性
Vue.prototype.$Big = Big;
new Vue({
el: "#app",
router,
store,
render: (h) => h(App),
});
- 组件里面使用
methods: {
toBig(num) {
num = Number(num);
// 判断输入的是否是数字 NaN 也属于数字类型
if (typeof num != 'number' && num != NaN) {
num = 0;
}
return new this.$Big(num);
},
count(){
let num1 = this.toBig(1);
let num2 = this.toBig(2);
let num3 = this.toBig(3);
let num4 = this.toBig(4);
// 例: 1 * 2 + 3 - 4
let num5 = num1.times(num2).plus(num3).minus(num4); // 链式调用
// 最后得出的结果是一个 big 对象,可以使用 Number() 转为数字
console.log(Number(num5))); // 1
}
}