bigNumber.js

为什么要使用bigNumber.js

为了解决精度丢失的问题,前端面试常见的一个问题就是‘0.1+0.2!=0.3’是为什么,0.1+0.2 = 0.30000000000000004,这在对数字精度要求比较高的项目中常常会出现bug,所以要使用bigNumber.js
官网的解释:A JavaScript library for arbitrary-precision arithmetic.(用于任意精度算术的JavaScript库。)

精度为什么丢失?

0.1+0.2 = 0.30000000000000004

  • 数据存储方式:js遵循国际 IEEE 754 标准,将数字存储为双精度浮点数。这种格式以 64 位存储数字,其中数字(分数)存储在位 0 到 52 中,指数存储在位 53 到 62 中,符号存储在位 63(正数为0负数为1) 中。整数的表示范围就是 -2^53 到 2^53 之间 。
  • 十进制整数转二进制方法:除2取余;十进制小数转二进制方法:乘2取整:
    0.1 * 2 = 0.2 # 0
    0.2 * 2 = 0.4 # 0
    0.4 * 2 = 0.8 # 0
    0.8 * 2 = 1.6 # 1
    0.6 * 2 = 1.2 # 1
    0.2 * 2 = 0.4 # 0
    从上面可以看出,0.1的二进制格式是:0.0001100011…。这是一个二进制无限循环小数,取前52位,所以一些小数存在计算机中天然就存在舍入误差
  • 计算机存储数据用的是二进制存储十进制,一些十进制的小数在存储为二进制的时候回变成无限小数。而js遵循国际IEEE754标准,将数字存储为双精度浮点数,这种格式以64位存储格式,数字存储在0到51位中,指数存储在52到62位中,符号位存储在63位中。所以二进制的无限小数只能存储前52位,(转换为10进制就是前17位)后面的位数被舍入了,在相加的过程中存在舍入误差。0.1+0.1===0.2的原因?存储的过程中也存在舍入误差,只是恰好等于0.2后面16个0

安装bigNumber.js

1、下载地址:
https://github.com/MikeMcl/bignumber.js/releases
2、安装命令:

npm install bignumber.js --save

3、引入

import BigNumber from 'bignumber.js'

使用

官网地址
备注:可以在官网控制台进行测试使用

一、BigNumber构造

BigNumber构造如下

y = new BigNumber(-1000)
y=>{
      c: [1000] // 数值
      e: 3//指数幂
      s: -1//正负
}

二、静态方法

备注:以下标题的格式如下: 方法全称 && 方法简称 方法作用

1、absoluteValue && .abs() 取绝对值
x = new BigNumber(-0.8)
y = x.abs()
//0.8
2、comparedTo && isEqualTo 比较大小

两个都是表示比较大小,功能略有差异

z = y.comparedTo(x)
z = y.isEqualTo(x)

comparedTo方法:y>x,返回1;y<x,返回-1;y===x,返回0,x为NaN时,返回NaN。

isEqualTo方法是在comparedTo方法的基础上实现的,x和y相等返回true,不等返回false

3、decimalPlaces && .dp(num,rm) 保留小数位

rm:指的是小数位的舍入方式,后文与之相同

x = new BigNumber(1234.5678)
x.dp(2)  //1234.57
x.dp()  //4  不给参数,返回小数位数
3、dividedBy && .div(num,base)

base:指的是数字的进制,后文与之相同

x = new BigNumber(355)
x.div(5)           // '71'
x.div(47, 16)     // '5'
//解释:47是十六进制的,即71
4、dividedToIntegerBy && .idiv(num,base) 整除

只取商的整数部分

x = new BigNumber(5)
x.idiv(0.7)  // '7'
5、exponentiatedBy && .pow(n) 指数运算
x = new BigNumber(0.7)
x.pow(2)            // '0.49'
6、.integerValue(rm) 取整数
x = new BigNumber(-12.7)
y.integerValue()              // '-13'
7、.isFinite() 判断Infinity 返回布尔值
8、.isGreaterThan && .gt(num,base) 判断是否更大
y.gt(x)    //y比x大返回true,否则返回false
9、.isGreaterThanOrEqualTo && .gte(num,base) 判断是否大于等于
10、.isInteger() 判断是否是整数 返回布尔值
11、.isLessThan && .lt(num,base) 判断是否小于
12、.isLessThanOrEqualTo && .lte(num,base) 判断是否小于等于
13、.isNaN()判断是否是NaN 返回布尔值
14、.isNegative()判断是否是负数 返回布尔值
15、.isPositive()判断是否是正数 返回布尔值
16、.isZero判断是否是0 返回布尔值
17、.minus(num,base) 减数运算
x = new BigNumber(0.3)
x.minus(0.1)                    // '0.2'
18、.modulo && .mod(num,base) 取余
x = new BigNumber(1)
x.mod(0.9)                   // '0.1'
19、multipliedBy&&.times(num,base) 乘法运算
x = new BigNumber(1)
x.times(5)                   // '5'
20、.negated() 取负值
x = new BigNumber(1)
x.negated()                  // '-1'
21、.plus()
x = new BigNumber(1)
x.plus(3)                  // '4'
22、.precision() &&.sd()保留小数位

.sd()
.sd(boolean)
.sd(num,rm)

x = new BigNumber(1234.56780000)
y = new BigNumber(1234567800)
x.sd()                // '8'
x.precision()         // '8'
x.sd(true)            // '8'
y.sd()                // '8'
y.sd(true)            // '10'
x.sd(6)               // '1234.57'
x.precision(6, BigNumber.ROUND_DOWN) // '1234.56'
  • 不传参:返回数字的位数(不计首尾的0)
  • 参数为true:返回数字的有效位数(包括尾部的0)
  • 参数为数字num,保留的有效位数
  • rm:当有参数num时生效,保留位数的模式,默认是四舍五入
23、.shiftedBy(n) 小数点移位
x = new BigNumber(1.23)
x.shiftedBy(-3)  //'0.00123'
x.shiftedBy(3)   //'1230'

参数n:小数点移动的位数,正数向右移动,负数向左移动

24、.squareRoot() && .sqrt() 开根号
x = new BigNumber(16)
y.sqrt()   //4
25、.toExponential() 科学计数法

.toExponential(dp,rm)

x = new BigNumber(265)
x.toExponential()  //'2.65e+2'
x.toExponential(1, 1)   // '2.6e+2'

dp:保留小数位
rm:保留位数的模式,默认是四舍五入

26、.toFixed(dp,rm) 保留小数位
x = new BigNumber(3.1415926)
x.toFixed(4)       // '3.1416'
x.toFixed(1, 1)   //   '3.1'

dp:保留小数位
rm:保留位数的模式,默认是四舍五入

27、.toFormat(dp,rm,format) 数据格式化
x = new BigNumber(3.1415926)
x.toFormat(4)       // '3.1416'
x.toFormat(1, 1)   //   '3.1'

dp:保留小数位
rm:保留位数的模式,默认是四舍五入
format:自定义要格式化的数据格式

const fmt = {
  prefix: 'start=>',    //给数据加前缀
  decimalSeparator: '.', //整数和小数之间的分隔符
  groupSeparator: ',', //整数部分分组隔离符
  groupSize: 3, // 整数部分分组大小
  secondaryGroupSize: 0, 
  fractionGroupSeparator: '-', // 小数部分分组隔离符
  fractionGroupSize: 2, // 整数部分分组大小
  suffix: '<=end'   // 给数据加后缀
}
x = new BigNumber(123456789.123456789)
x.toFormat(fmt) //  'start=>123,456,789.12-34-56-79<=end'
28、.toFraction(max) 小数转分数
pi = new BigNumber('3.14159265358')
pi.toFraction()                 // '157079632679,50000000000'
pi.toFraction(100000)           // '312689, 99532'

备注:以数组形式返回[分子,分母],数据以BigNumber格式返回
max:分母最大不能超过max

29、.toJSON() 转换为字符串
x = new BigNumber(123456)
x.toJSON()  //'123456'
30、.toNumber() 转换为数字

转换为非BigNumber格式的数字

x = new BigNumber(456.789)
x.toNumber()  //456.789
31、.toPrecision() 保存精度
32、.toString() 转换为字符串
33、.valueOf() 转换为字符串

三、方法

  • 7
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值