BigNumber.js 讲解

在这里插入图片描述
JavaScript因为存在计算的精度问题,所以直接计算就可能会导致各种各样的bug,为了解决这个问题,就要使用BigNumber.js这个库。

至于为什么JavaScript会有精度问题呢,可以看https://github.com/camsong/blog/issues/9。简单来说就是因为:JavaScript中所有的数字(包括整数和小数)都只有一种类型–Number。它的实现遵循IEEE 754标准,使用64位固定长度来表示,也就是标准的double双精度浮点数。它的优点是可以归一化处理整数和小数,节省储存空间。而实际计算的时候会转换成二进制计算再转成十进制。进制转换之后会很长,舍去一部分,计算再转回来,就有了精度误差。

BigNumber.js是一个用于任意精度计算的js库。可以在 官方文档 的console中测试使用。也可以通过 npm install bignumber.js --save 来安装。然后 import BigNumber from ‘bignumber.js’ 来引入使用。他的大概原理是将所有数字当做字符串,重新实现了计算逻辑。缺点是性能比原生的差很多。

具体用法可以参考以下资料:

  • https://mikemcl.github.io/bignumber.js/

constructor

/*
*    n {number|string|BigNumber} A numeric value.
*   [b] {number} The base of n. Integer, 2 to ALPHABET.length inclusive.
*/
function BigNumber(n, b) {
    
    
   
}

静态方法

clone()

生成一个独立的BigNumber构造函数

var BN = BigNumber.clone()
BN(1).div(3).toNumber() //0.3333333333333333

config()

为这个独立的BigNumber构造函数设置参数
主要包括以下几个参数:

  1. DECIMAL_PLACES(默认值:20) 用于设置小数位数。在除法、开方、指数计算时会用到。
var BN = BigNumber.clone()
BN.config({
    
    DECIMAL_PLACES:4})
BN(1).div(3).toNumber() //0.3333,注意跟上面计算结果的区别
  1. ROUNDING_MODE(默认值4) 舍入模式,取值的意义可参照 文档
//取值范围:
BigNumber.ROUND_UP = 0;         //远离0方向舍入
BigNumber.ROUND_DOWN = 1;       //向0方向舍入
BigNumber.ROUND_CEIL = 2;       //向正无限大舍入
BigNumber.ROUND_FLOOR = 3;      //向负无限大舍入
BigNumber.ROUND_HALF_UP = 4;    //四舍五入:向最接近的数字方向舍入,如果与两个相邻数字的距离相等,则向上舍入。
BigNumber.ROUND_HALF_DOWN = 5;  //向最接近的数字方向舍入,如果与两个相邻数字的距离相等,则向下舍入。
BigNumber.ROUND_HALF_EVEN = 6;  //向最接近数字方向舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入
BigNumber.ROUND_HALF_CEIL = 7;
BigNumber.ROUND_HALF_FLOOR = 8;
  1. EXPONENTIAL_AT(默认值[-7,20]) 指数计数法
  2. RANGE(默认值[-1e+9,1e+9])
  3. CRYPTO(默认值 false) 用于设置BigNumber.random()的随机生成算法。如果无法设置为true,则使用Math.random()生成随机值。
  4. MODULO_MODE(默认值:ROUND_DOWN) 取模运算的模式
  5. POW_PRECISION(默认值:0) pow运算结果的精度
  6. FORMATE(格式化对应的设置)
默认值:
BigNumber.config().FORMAT
==============================
{
    
    
decimalSeparator: "."
fractionGroupSeparator: " "
fractionGroupSize: 0
groupSeparator: ","
groupSize: 3
secondaryGroupSize: 0
}

获取数组中的最大值/最小值

maximum([]),minimum([])

返回一个伪随机值,参数可以指定小数点位数

random([precision])

实例方法

加法:.plus(n [, base]) ⇒ BigNumber

0.1 + 0.2                       // 0.30000000000000004
x = new BigNumber(0.1)
y = x.plus(0.2)                 // '0.3'
BigNumber(0.7).plus(x).plus(y)  // '1'
x.plus('0.1', 8)                // '0.225'

减法:.minus(n [, base]) ⇒ BigNumber

0.3 - 0.1                       // 0.19999999999999998
x = new BigNumber(0.3)
x.minus(0.1)                    // '0.2'
x.minus(0.6, 20)                // '0'

乘法:.times(n [, base]) ⇒ BigNumber; m.ultipliedBy(n [, base]) ⇒ BigNumber;

扫描二维码关注公众号,回复: 13383052 查看本文章
0.6 * 3                         // 1.7999999999999998
x = new BigNumber(0.6)
y = x.multipliedBy(3)           // '1.8'
BigNumber('7e+500').times(y)    // '1.26e+501'
x.multipliedBy('-a', 16)        // '-6

普通除法运算: .div(n [, base]) ⇒ BigNumber; .dividedBy(n [, base]) ⇒ BigNumber

x = new BigNumber(355)
y = new BigNumber(113)
x.dividedBy(y)                  // '3.14159292035398230088'
x.div(5)                        // '71'
x.div(47, 16)                   // '5'

注意: 除法计算结果会根据DECIMAL_PLACES和ROUNDING_MODE两个属性设置进行舍入。

除法,返回整数: .idiv(n [, base]) ⇒ BigNumber;.dividedToIntegerByv(n [, base]) ⇒ BigNumber

x = new BigNumber(355)
y = new BigNumber(113)
x.dividedBy(y)                  // '3.14159292035398230088'
x.div(5)                        // '71'
x.div(47, 16)                   // '5'

取模/取余: .mod(n [, base]) ⇒ BigNumber;modulo.(n [, base]) ⇒ BigNumber

1 % 0.9                         // 0.09999999999999998
x = new BigNumber(1)
x.modulo(0.9)                   // '0.1'
y = new BigNumber(33)
y.mod('a', 33)                  // '3'

注意: 取模/取余运算受MODULO_MODE设置影响
指数运算: .pow(n [, m]) ⇒ BigNumber;.exponentiatedBy(n [, m]) ⇒ BigNumber

Math.pow(0.7, 2)                // 0.48999999999999994
x = new BigNumber(0.7)
x.exponentiatedBy(2)            // '0.49'
BigNumber(3).pow(-2)            // '0.11111111111111111111'

比较大小: .comparedTo(n [, base]) ⇒ number
比较结果,参考如下表:

1	操作数>n
-1	操作数<n
0	操作数==n
null	操作数或者n不是数字

举例:

x = new BigNumber(Infinity)
y = new BigNumber(5)
x.comparedTo(y)                 // 1
x.comparedTo(x.minus(1))        // 0
y.comparedTo(NaN)               // null
y.comparedTo('110', 2)          // -1

猜你喜欢

转载自blog.csdn.net/weixin_40639095/article/details/110648252