1. 最大安全整数
我们在js中能使用的最大数是多少?
根据262.ecma 21.1.2.7是,在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等,一旦用了,就会报错;
3.2 不能和任何 Number 实例混合运算
要想和普通的数字进行运算, 两者必须转换成同一种类型。
上图中普通整数5和大整数3n相加,就会报错,必须要做明确的数字类型变换;
3.3 BigInt转成变Number时,可能会丢失精度
在两种类型来回转换时要小心,因为 BigInt 变量在转换成 Number 变量时可能会丢失精度。
3.4 BigInt不能进行JSON转换
不能使用JSON.stringjify和JSON.parse对BigInt进行转换。
3.5 BigInt 不支持单目 (+) 运算符
因为有很多使用时的小限制,所以代码时一定要注意,不要和普能Number类型数混在一起运算,一定要做明确的类型转换。
浏览器支持
大整数BigInt的浏览器支持程度已经很高了,绝大部分PC浏览器和node环境都支持,手机浏览器还需要最新版本才能支持,这个要注意。