BigInt的简单了解

440 阅读3分钟

1. 最大安全整数

我们在js中能使用的最大数是多少? 根据262.ecma 21.1.2.79ADB58A0-E806-4383-9CC7-489E953AD3E7.png,在JS里对应的变量是Number.MAX_VALUE

不过,对我们日常使用时,还有另外一个变量:Number.MAX_SAFE_INTEGER,这是JS精确算术运算的整数范围,为正负2的53次方,也即从最小值-9007199254740992到最大值+9007199254740992之间的范围。对于超过这个范围的整数,JavaScript依旧可以进行运算,但却不保证运算结果的精度。比如以下代码:

var x = 9223372036854775807;
console.log(x === x + 1); 
console.log(9223372036854775807 + 1000);

代码第二行打印出来的竟然是true,第三行打印出来的不是9223372036854776807,而是9223372036854776000。这就是因为超出了最安全整数,JS已经不能保证计算结果了。

要如何解决这个问题呢?

2. BigInt

为了解决这个问题ecma引入了一个新的类型:BigInt,在标准Ecma 6.1.6.2 The BigInt Type中是这么说的

The BigInt type represents an integer value. The value may be any size and is not limited to a particular bit-width. Generally, where not otherwise noted, operations are designed to return exact mathematically-based answers.

也就是说BigInt的值可以无限大;它的计算结果,就是我们认为的数学里应该有的结果。

声明一个BigInt的办法很多,比如直接在数字后加n,如 10n,下面给出了几种方式

const theBiggestInt = 9007199254740991n;

const alsoHuge = BigInt(9007199254740991);
// ↪ 9007199254740991n

const hugeString = BigInt("9007199254740991");
// ↪ 9007199254740991n

const hugeHex = BigInt("0x1fffffffffffff");
// ↪ 9007199254740991n

const hugeBin = BigInt("0b11111111111111111111111111111111111111111111111111111");
// ↪ 9007199254740991n

3. 使用限制

虽然可以方便的声明一个BigInt,不过在使用中还是有很多限制的,一不小心就会报错。

3.1 不能使用Math对象中的方法

Math中各种函数都不能使用,比如abs\pow\ceil\floor等,一旦用了,就会报错;

42A5356A-F98D-4D21-BAB8-7B8F35FDFA97.png

3.2 不能和任何 Number 实例混合运算

要想和普通的数字进行运算, 两者必须转换成同一种类型。

5E5DF356-C4DA-4F18-B9D1-72AB4C0B4BA8.png 上图中普通整数5和大整数3n相加,就会报错,必须要做明确的数字类型变换;

3.3 BigInt转成变Number时,可能会丢失精度

在两种类型来回转换时要小心,因为 BigInt 变量在转换成 Number 变量时可能会丢失精度。

E8924A87-BD89-4576-8231-17E6FBD346D0.png

3.4 BigInt不能进行JSON转换

不能使用JSON.stringjify和JSON.parse对BigInt进行转换。

6054EAD9-6ADF-4E05-9283-F395BF7AEB36.png

3.5 BigInt 不支持单目 (+) 运算符

F26BB5C4-DCA0-4EBF-9673-9CCC1E348F6D.png

因为有很多使用时的小限制,所以代码时一定要注意,不要和普能Number类型数混在一起运算,一定要做明确的类型转换。

浏览器支持

大整数BigInt的浏览器支持程度已经很高了,绝大部分PC浏览器和node环境都支持,手机浏览器还需要最新版本才能支持,这个要注意。

9898A145-1C7C-4E57-8086-36E2CA361D1E.png