• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • BigInt

    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一起使用:+*-**%。除>>>(无符号右移)之外的位操作(en-US)也可以支持。因为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
    


    比较

    BigIntNumber不是严格相等的,但是宽松相等的。

    0n === 0
    // ↪ false
    
    0n == 0
    // ↪ true
    

    NumberBigInt可以进行比较。

    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(en-US)||,&&,和!的操作数;或者用于在像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()

    创建BigInt对象。


    静态方法

    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()方法。


    使用建议

    转化

    由于在NumberBigInt之间进行转换会损失精度,因而建议仅在值可能大于 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
    

    下篇:BigInt()