JS之BigNumber.js 讲解

简介: JS之BigNumber.js 讲解

20201204153103177.jpg


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/


consyructor


/*
*    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,注意跟上面计算结果的区别


2.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;


3.EXPONENTIAL_AT(默认值[-7,20]) 指数计数法


4.RANGE(默认值[-1e+9,1e+9])


5.CRYPTO(默认值 false) 用于设置BigNumber.random()的随机生成算法。如果无法设置为true,则使用Math.random()生成随机值。


6.MODULO_MODE(默认值:ROUND_DOWN) 取模运算的模式


7.POW_PRECISION(默认值:0) pow运算结果的精度


8.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;


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
目录
相关文章
|
JavaScript 前端开发
JS浮点数精度问题及高精度小数运算:BigNumber解决方案
JS浮点数精度问题及高精度小数运算:BigNumber解决方案
1925 0
|
JavaScript 前端开发
JavaScript:解决计算精度问题/mathjs/bignumber.js/big.js/decimal.js
JavaScript:解决计算精度问题/mathjs/bignumber.js/big.js/decimal.js
2266 0
|
JSON 前端开发 JavaScript
前端使用lottie-web,使用AE导出的JSON动画贴心教程
前端使用lottie-web,使用AE导出的JSON动画贴心教程
2297 2
|
12月前
|
前端开发 测试技术 API
2025年API开发必备:10款优秀Postman替代工具大盘点
API测试在现代开发中至关重要,Postman虽为首选,但市场上涌现出许多优秀替代工具。本文精选2025年10款好评如潮的API测试工具:Apifox、Insomnia、Hoppscotch、Paw、Talend API Tester、HTTPie、ARC、Swagger UI、SoapUI和Thunder Client。这些工具各具特色,满足不同需求,如团队协作、开源易用、自动化测试等。无论是简洁轻量还是功能全面,总有一款适合你的团队,助力效率提升。
6745 122
|
10月前
|
IDE 前端开发 开发工具
用通义灵码IDE做产品高保真原型和前端页面
通义灵码IDE助力高效开发,告别传统Axure原型图的繁琐沟通。通过该工具可直接生成高保真产品原型与前端页面,大幅提升客户确认效率及满意度。现已将相关演示发布至B站(https://www.bilibili.com/video/BV18qT7ziEb7/?vd_source=dc6a6864c895818db6ce4170d50b3557),欢迎体验!用直观操作代替反复说明,让交付更流畅。
|
JavaScript 前端开发
JavaScript 数字精度丢失问题
【10月更文挑战第24天】解决 JavaScript 数字精度丢失的问题需要综合考虑多种因素,并根据具体情况选择合适的方法。通过合理的处理和预防,可以在一定程度上减少精度误差的影响,确保计算结果的准确性。
|
JavaScript API 索引
js中的reduce()方法 讲解 和实现
`reduce()` 方法对数组元素依次应用一个回调函数,将结果累计并最终返回单一值。语法为 `reduce(callback(accumulator, currentValue, currentIndex, array), initialValue)`。参数包括累计器(初次为初始值或首元素)、当前元素值、索引及数组自身。此方法需返回值供下一轮迭代使用。常见应用场景包括计算数组总和与平均值、统计元素频率、过滤与转换数组内容及去除重复项等。例如,可通过 `reduce()` 快速计算 `[1, 2, 3, 4, 5]` 的总和或对对象属性值求和。此外,还可自定义实现 `reduce()` 方法
7309 1
|
Java Windows
如何在windows上运行jar包/JAR文件 如何在cmd上运行 jar包 保姆级教程 超详细
本文提供了一个详细的教程,解释了如何在Windows操作系统的命令提示符(cmd)中运行JAR文件。
10182 1
|
存储 前端开发 Java
学成在线笔记+踩坑(5)——【媒资模块】上传视频,断点续传
上传视频,MinIO断点续传、检查文件/分块、上传分块、合并分块
学成在线笔记+踩坑(5)——【媒资模块】上传视频,断点续传
|
JavaScript BI 数据处理
computed 与 method 结合使用的示例
【10月更文挑战第15天】Computed 与 Method 的结合使用为 Vue 应用的开发提供了更多的可能性和灵活性。通过合理运用,可以更好地处理数据计算和逻辑操作,提高应用的性能和可维护性。在实际开发中,要根据具体需求和场景,巧妙地将两者结合起来,以达到最佳效果。
240 3