使用JS中的BigInt解决大数运算

由于JS存在数值限制,整数范围是[-2^53, 2^53],在这个范围之外就是失真,看一个例子:

console.log(Math.pow(2, 53));//9007199254740992
console.log(Math.pow(2,53) + 1);//9007199254740992
console.log(-Math.pow(2, 53));//-9007199254740992
console.log(-Math.pow(2, 53) - 1);//-9007199254740992

可以看到2^53+1应该输出的是9007199254740993,但是由于数值超过了JS的整数限制,造成了数值溢出。负数也是同样的原因。
这种性质无疑会对大数运算带来一定的阻碍,像常见的斐波那契数列和阶乘,随着参数的增大,计算结果在某个阀值就会溢出,因此这就使得JS无法进行金融和科技上的精密计算。
ES2020 引入了一种新的数据类型 BigInt(大整数),这是 ECMAScript 的第八种数据类型。BigInt 只用来表示整数,没有位数的限制,任何位数的整数都可以精确表示。
来看一个实例:

var x = 123456789;
var y = 987654321;
console.log(x*y);//121932631112635260

即使不用检验,也可以看出,结果显然不正确,因为x与y个位数相乘得到的是9,而结果的末尾是0。
那么使用BigInt后呢?

var x = 123456789n;
var y = 987654321n;
console.log(x*y);//121932631112635269n

得到的结果是正确的,感兴趣的话可以用字符串模拟乘法运算法则检验一下。
可以看到BigInt与Number的区别在于后缀n,那么在刷题过程中,可以通过toString()的方法,把n去掉。

var x = 123456789n;
var y = 987654321n;
console.log(x*y);//121932631112635269n
console.log((x*y).toString());//121932631112635269

因此BigInt值与Number值并不是同一类型:

var a = 11n;
var b = 11;
console.log(typeof a);//bigint
console.log(typeof b);//number
console.log(a === b)//false

但是在一些语法上是相似的:

  1. 能够接受其他进制的数值,并转为十进制:
console.log(Number(0b11));//3
console.log(BigInt(0b11n));//3n
console.log(Number(0o71));//57
console.log(BigInt(0o71n));//57n
console.log(Number(0xA));//10
console.log(BigInt(0xAn));//10n

当然,使用BigInt进行转换时,也可以省略后缀n,但是不推荐这样做

console.log(BigInt(0b11));//3n
  1. 使用一元运算符进行简单的计算:
var x = 6n;
var y = 4n;
console.log(x + y);//10n
console.log(x - y);//2n
console.log(x * y);//24n
console.log(x / y);//1n
console.log(x % y);//2n
var x = 6;
var y = 4;
console.log(x + y);//10
console.log(x - y);//2
console.log(x * y);//24
console.log(x / y);//1.5
console.log(x % y);//2

不同之处就是整除了,BigInt会返回整数,像C的整除一样,但是JS的整除返回的是在精度范围内的数字,也可以借助这一点来实现一些需求,例如在获取一个整数每位上的数字运算中,就可以现将这个这个整数转为BigInt类型,然后再计算,这样就省略了过程中借助parseInt()的转化了,来看一个例子:

var num = 123456789;
var sum = 0;
while(num){
    sum += num%10;
    num = parseInt(num/10);
}
console.log(sum);
var num = 123456789;
num = BigInt(num);
var sum = 0n;
while(num != 0n){
    sum += num % 10n;
    num = num/10n;
}
console.log(sum);

好吧,虽然在这个例子中看起来很蠢,但是在一些条件下,确实可以起到很有效的作用。
需要注意的是,BigInt与Number进行运算时,会报错:

console.log(1 + 2n);

TypeError: Cannot mix BigInt and other types, use explicit conversions

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值