JS BigInt
BigInt 是一种内置对象,可以表示大于 253-1 的整数。而在 Javascript 中,Number 基本类型可以精确表示的最大整数是 253-1 。BigInt 可以表示任意大的整数。
BigInt 现在处在 ECMAScript 标准化过程中的 第三阶段 。
当它进入第四阶段草案,也就是最终标准时, BigInt 将成为 Javacript 中的第二种内置数值类型。
BigInt 可能会成为自 ES2015 引入 Symbol 之后,增加的第一个新的内置类型。
语法
BigInt(value);
参数
value
创建对象的数值。可以是字符串或者整数。
注意, BigInt() 不是构造函数,因此不能使用 new 操作符。
描述
可以用在一个整数字面量后面加 n 的方式定义一个 BigInt ,如:10n,或者调用函数 BigInt()。
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 包装的 BigInts 使用 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 值转换为一个 -2width-1 与 2width-1-1 之间的有符号整数。
BigInt.asUintN()
将一个 BigInt 值转换为 0 与 2width-1 之间的无符号整数。
属性
BigInt.prototype
可以对 BigInt 对象增加属性。
BigInt 实例
所有 BigInt 实例继承自 BigInt.prototype 。 BigInt 构造函数的 prototype 对象可以被修改,并会影响所有 BigInt 实例。
方法
BigInt.prototype.toLocaleString()
Returns a string with a language-sensitive representation of this number. Overrides the Object.prototype.toLocaleString() method.
BigInt.prototype.toString()
Returns a string representing the specified object in the specified radix (base). Overrides the Object.prototype.toString() method.
BigInt.prototype.valueOf()
Returns the primitive value of the specified object. Overrides the Object.prototype.valueOf() method.
使用建议
转化
由于在 Number 与 BigInt 之间进行转换会损失精度,因而建议但值可能大于 253 时仅使用 BigInt 类型,并且不在两种类型之间进行相互转换。
密码学
由于对 BigInt 的操作不是常数时间的,因而 BigInt 不适合用于密码学。
例子
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
标准
标准 | 状态 |
---|---|
BigInt | 第 3 阶段 |