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 阶段

AXIHE / 精选资源

浏览全部教程

面试题

学习网站

前端培训
自己甄别

前端书籍

关于朱安邦

我叫 朱安邦,阿西河的站长,在杭州。

以前是一名平面设计师,后来开始接接触前端开发,主要研究前端技术中的JS方向。

业余时间我喜欢分享和交流自己的技术,欢迎大家关注我的 Bilibili

关注我: Github / 知乎

于2021年离开前端领域,目前重心放在研究区块链上面了

我叫朱安邦,阿西河的站长

目前在杭州从事区块链周边的开发工作,机械专业,以前从事平面设计工作。

2014年底脱产在老家自学6个月的前端技术,自学期间几乎从未出过家门,最终找到了满意的前端工作。更多>

于2021年离开前端领域,目前从事区块链方面工作了