BigInt
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2020.
BigInt
是一种内置对象,它提供了一种方法来表示大于 2^53 - 1
的整数。这原本是 Javascript 中可以用 Number
表示的最大数字。BigInt
可以表示任意大的整数。
描述
可以用在一个整数字面量后面加 n
的方式定义一个 BigInt
,如:10n
,或者调用函数 BigInt()
(但不包含 new
运算符)并传递一个整数值或字符串值。
const theBiggestInt = 9007199254740991n;
const alsoHuge = BigInt(9007199254740991);
// ↪ 9007199254740991n
const hugeString = BigInt("9007199254740991");
// ↪ 9007199254740991n
const hugeHex = BigInt("0x1fffffffffffff");
// ↪ 9007199254740991n
const hugeBin = BigInt(
"0b11111111111111111111111111111111111111111111111111111",
);
// ↪ 9007199254740991n
它在某些方面类似于 Number
,但是也有几个关键的不同点:不能用于 Math
对象中的方法;不能和任何 Number
实例混合运算,两者必须转换成同一种类型。在两种类型来回转换时要小心,因为 BigInt
变量在转换成 Number
变量时可能会丢失精度。
类型信息
使用 typeof
测试时, BigInt
对象返回 "bigint" :
typeof 1n === "bigint"; // true
typeof BigInt("1") === "bigint"; // true
使用 Object
包装后, BigInt
被认为是一个普通 "object" :
typeof Object(1n) === "object"; // true
运算
以下操作符可以和 BigInt
一起使用: +
、*
、-
、**
、%
。除 >>>
(无符号右移)之外的 位操作 也可以支持。因为 BigInt
都是有符号的, >>>
(无符号右移)不能用于 BigInt
。为了兼容 asm.js,BigInt
不支持单目 (+
) 运算符。
const previousMaxSafe = BigInt(Number.MAX_SAFE_INTEGER);
// ↪ 9007199254740991n
const maxPlusOne = previousMaxSafe + 1n;
// ↪ 9007199254740992n
const theFuture = previousMaxSafe + 2n;
// ↪ 9007199254740993n, this works now!
const multi = previousMaxSafe * 2n;
// ↪ 18014398509481982n
const subtr = multi – 10n;
// ↪ 18014398509481972n
const mod = multi % 10n;
// ↪ 2n
const bigN = 2n ** 54n;
// ↪ 18014398509481984n
bigN * -1n
// ↪ –18014398509481984n
/
操作符对于整数的运算也没问题。可是因为这些变量是 BigInt
而不是 BigDecimal
,该操作符结果会向零取整,也就是说不会返回小数部分。
警告:
当使用 BigInt
时,带小数的运算会被取整。
const expected = 4n / 2n;
// ↪ 2n
const rounded = 5n / 2n;
// ↪ 2n, not 2.5n
比较
BigInt
和 Number
不是严格相等的,但是宽松相等的。
0n === 0;
// ↪ false
0n == 0;
// ↪ true
Number
和 BigInt
可以进行比较。
1n < 2;
// ↪ true
2n > 1;
// ↪ true
2 > 2;
// ↪ false
2n > 2;
// ↪ false
2n >= 2;
// ↪ true
两者也可以混在一个数组内并排序。
const mixed = [4n, 6, -12n, 10, 4, 0, 0n];
// ↪ [4n, 6, -12n, 10, 4, 0, 0n]
mixed.sort();
// ↪ [-12n, 0, 0n, 10, 4n, 4, 6]
注意被 Object
包装的 BigInt
使用 object 的比较规则进行比较,只用同一个对象在比较时才会相等。
0n === Object(0n); // false
Object(0n) === Object(0n); // false
const o = Object(0n);
o === o; // true
条件
BigInt
在需要转换成 Boolean
的时表现跟 Number
类似:如通过 Boolean
函数转换;用于 Logical Operators
||
, &&
, 和 !
的操作数;或者用于在像 if statement
这样的条件语句中。
if (0n) {
console.log("Hello from the if!");
} else {
console.log("Hello from the else!");
}
// ↪ "Hello from the else!"
0n || 12n;
// ↪ 12n
0n && 12n;
// ↪ 0n
Boolean(0n);
// ↪ false
Boolean(12n);
// ↪ true
!12n;
// ↪ false
!0n;
// ↪ true
构造器
静态方法
BigInt.asIntN()
-
将 BigInt 值转换为一个 -2^(width-1) 与 2^(width-1) - 1 之间的有符号整数。
BigInt.asUintN()
-
将一个 BigInt 值转换为 0 与 2^(width) - 1 之间的无符号整数。
实例方法
BigInt.prototype.toLocaleString()
-
返回此数字的 language-sensitive 形式的字符串。覆盖
Object.prototype.toLocaleString()
方法。 BigInt.prototype.toString()
-
返回以指定基数 (base) 表示指定数字的字符串。覆盖
Object.prototype.toString()
方法。 BigInt.prototype.valueOf()
-
返回指定对象的基元值。覆盖
Object.prototype.valueOf()
方法。
使用建议
转化
由于在 Number
与 BigInt
之间进行转换会损失精度,因而建议仅在值可能大于 2^53 时使用 BigInt
类型,并且不在两种类型之间进行相互转换。
密码学
由于对 BigInt
的操作不是常数时间的,因而 BigInt
不适合用于密码学。
在 JSON 中使用
对任何 BigInt
值使用 JSON.stringify()
都会引发 TypeError
,因为默认情况下 BigInt
值不会在 JSON
中序列化。但是,如果需要,可以实现 toJSON
方法:
BigInt.prototype.toJSON = function () {
return this.toString();
};
JSON.stringify
现在生成如下字符串,而不是抛出异常:
JSON.stringify(BigInt(1));
// '"1"'
示例
Calculating Primes
function isPrime(p) {
for (let i = 2n; i * i <= p; i++) {
if (p % i === 0n) return false;
}
return true;
}
// Takes a BigInt as an argument and returns a BigInt
function nthPrime(nth) {
let maybePrime = 2n;
let prime = 0n;
while (nth >= 0n) {
if (isPrime(maybePrime)) {
nth -= 1n;
prime = maybePrime;
}
maybePrime += 1n;
}
return prime;
}
nthPrime(20n);
// ↪ 73n
规范
Specification |
---|
ECMAScript Language Specification # sec-bigint-objects |
浏览器兼容性
BCD tables only load in the browser