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 前端开发
JavaScript:解决计算精度问题/mathjs/bignumber.js/big.js/decimal.js
JavaScript:解决计算精度问题/mathjs/bignumber.js/big.js/decimal.js
2607 0
|
前端开发 Java 开发者
深入理解Spring Boot中的@Service注解
【4月更文挑战第22天】在 Spring Boot 应用开发中,@Service 注解扮演着特定的角色,主要用于标识服务层组件。本篇技术博客将全面探讨 @Service 注解的概念,并提供实际的应用示例,帮助开发者理解如何有效地使用这一注解来优化应用的服务层架构
3706 1
|
JavaScript 前端开发 API
浅谈Vue3——父子组件传值
浅谈Vue3——父子组件传值
1238 0
|
8月前
|
JavaScript 前端开发 定位技术
Vue项目中的虚拟滚动:提升页面渲染性能的最佳实践
本文介绍虚拟滚动技术及其在Vue项目中的应用,通过vue-virtual-scroller实现大数据量下长列表的高性能渲染,提升页面流畅度与用户体验,适用于地图轨迹等业务场景。
1876 0
|
IDE 前端开发 开发工具
用通义灵码IDE做产品高保真原型和前端页面
通义灵码IDE助力高效开发,告别传统Axure原型图的繁琐沟通。通过该工具可直接生成高保真产品原型与前端页面,大幅提升客户确认效率及满意度。现已将相关演示发布至B站(https://www.bilibili.com/video/BV18qT7ziEb7/?vd_source=dc6a6864c895818db6ce4170d50b3557),欢迎体验!用直观操作代替反复说明,让交付更流畅。
1037 1
|
资源调度 容器 流计算
Flink on YARN(上):一张图轻松掌握基础架构与启动流程
本文基于FLIP-6重构后的资源调度模型介绍Flink on YARN应用启动全流程,解答客户端和Flink Cluster的常见问题,分享相关问题的排查思路。
Flink on YARN(上):一张图轻松掌握基础架构与启动流程
|
缓存 资源调度
解决node升级到18版本node-sass安装问题
解决node升级到18版本node-sass安装问题
4. 解决uni-app开发过程中view、image等标签出现诸如“出现错误:类型“{ class: string; }”的参数不能赋给类型“.......”
4. 解决uni-app开发过程中view、image等标签出现诸如“出现错误:类型“{ class: string; }”的参数不能赋给类型“.......”
1450 0
|
机器人 数据中心
几个AC/DC电源模块的工业应用场景案例
几个AC/DC电源模块的工业应用场景案例
几个AC/DC电源模块的工业应用场景案例
|
存储 JavaScript 前端开发
Vue中通过集成Quill富文本编辑器实现公告的发布。Vue项目中vue-quill-editor的安装与使用【实战开发应用】
文章展示了在Vue项目中通过集成Quill富文本编辑器实现公告功能的完整开发过程,包括前端的公告发布、修改、删除操作以及后端的数据存储和处理逻辑。
Vue中通过集成Quill富文本编辑器实现公告的发布。Vue项目中vue-quill-editor的安装与使用【实战开发应用】

热门文章

最新文章