vault backup: 2026-11-07 16:33:44
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
由于JS存在数值限制,整数范围是[-2^53, 2^53],在这个范围之外就是失真,看一个例子:
|
||||
|
||||
```javascript
|
||||
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 只用来表示整数,没有位数的限制,任何位数的整数都可以`精确`表示。
|
||||
来看一个实例:
|
||||
|
||||
```javascript
|
||||
var x = 123456789;
|
||||
var y = 987654321;
|
||||
console.log(x*y);//121932631112635260
|
||||
```
|
||||
|
||||
即使不用检验,也可以看出,结果显然不正确,因为x与y个位数相乘得到的是9,而结果的末尾是0。
|
||||
那么使用BigInt后呢?
|
||||
|
||||
```javascript
|
||||
var x = 123456789n;
|
||||
var y = 987654321n;
|
||||
console.log(x*y);//121932631112635269n
|
||||
```
|
||||
|
||||
得到的结果是正确的,感兴趣的话可以用字符串模拟乘法运算法则检验一下。
|
||||
可以看到BigInt与Number的区别在于后缀n,那么在刷题过程中,可以通过toString()的方法,把n去掉。
|
||||
|
||||
```javascript
|
||||
var x = 123456789n;
|
||||
var y = 987654321n;
|
||||
console.log(x*y);//121932631112635269n
|
||||
console.log((x*y).toString());//121932631112635269
|
||||
```
|
||||
|
||||
因此BigInt值与Number值并不是同一类型:
|
||||
|
||||
```javascript
|
||||
var a = 11n;
|
||||
var b = 11;
|
||||
console.log(typeof a);//bigint
|
||||
console.log(typeof b);//number
|
||||
console.log(a === b)//false
|
||||
```
|
||||
|
||||
但是在一些语法上是相似的:
|
||||
|
||||
1. 能够接受其他进制的数值,并转为十进制:
|
||||
|
||||
```javascript
|
||||
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,**但是不推荐这样做**。
|
||||
|
||||
```javascript
|
||||
console.log(BigInt(0b11));//3n
|
||||
```
|
||||
|
||||
2. 使用一元运算符进行简单的计算:
|
||||
|
||||
```javascript
|
||||
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
|
||||
```
|
||||
|
||||
```javascript
|
||||
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()`的转化了,来看一个例子:
|
||||
|
||||
```javascript
|
||||
var num = 123456789;
|
||||
var sum = 0;
|
||||
while(num){
|
||||
sum += num%10;
|
||||
num = parseInt(num/10);
|
||||
}
|
||||
console.log(sum);
|
||||
```
|
||||
|
||||
```javascript
|
||||
var num = 123456789;
|
||||
num = BigInt(num);
|
||||
var sum = 0n;
|
||||
while(num != 0n){
|
||||
sum += num % 10n;
|
||||
num = num/10n;
|
||||
}
|
||||
console.log(sum);
|
||||
```
|
||||
|
||||
好吧,虽然在这个例子中看起来很蠢,但是在一些条件下,确实可以起到很有效的作用。
|
||||
需要注意的是,BigInt与Number进行运算时,会报错:
|
||||
|
||||
```javascript
|
||||
console.log(1 + 2n);
|
||||
```
|
||||
|
||||
> TypeError: Cannot mix BigInt and other types, use explicit conversions
|
||||
Reference in New Issue
Block a user