2020年9月21日

BigInt

最近の追加
これは、言語への最近の追加です。現在のサポート状況は https://caniuse.dokyumento.jp/#feat=bigint で確認できます。

BigInt は、任意の長さの整数をサポートする特別な数値型です。

BigInt は、整数リテラルの末尾に n を追加するか、文字列や数値などから BigInt を作成する関数 BigInt を呼び出すことで作成されます。

const bigint = 1234567890123456789012345678901234567890n;

const sameBigint = BigInt("1234567890123456789012345678901234567890");

const bigintFromNumber = BigInt(10); // same as 10n

算術演算子

BigInt は、ほとんどの場合、通常の数値のように使用できます。例:

alert(1n + 2n); // 3

alert(5n / 2n); // 2

注意: 除算 5/2 は、小数部分なしでゼロに向かって丸められた結果を返します。BigInt に対するすべての演算は BigInt を返します。

BigInt と通常の数値を混在させることはできません

alert(1n + 2); // Error: Cannot mix BigInt and other types

必要に応じて明示的に変換する必要があります。BigInt() または Number() を使用します。以下のように

let bigint = 1n;
let number = 2;

// number to bigint
alert(bigint + BigInt(number)); // 3

// bigint to number
alert(Number(bigint) + number); // 3

変換操作は常にサイレントであり、エラーを発生させることはありませんが、BigInt が大きすぎて数値型に収まらない場合、余分なビットが切り捨てられるため、このような変換を行う際には注意が必要です。

単項プラスは BigInt ではサポートされていません

単項プラス演算子 +value は、value を数値に変換する一般的な方法です。

混乱を避けるため、BigInt ではサポートされていません

let bigint = 1n;

alert( +bigint ); // error

したがって、BigInt を数値に変換するには Number() を使用する必要があります。

比較

<> などの比較は、BigInt と数値で正常に機能します

alert( 2n > 1n ); // true

alert( 2n > 1 ); // true

ただし、数値と BigInt は異なる型に属するため、== で等しくなることはあっても、厳密に等しい === ことはないことに注意してください

alert( 1 == 1n ); // true

alert( 1 === 1n ); // false

ブール演算

if またはその他のブール演算内では、BigInt は数値のように動作します。

たとえば、if では、BigInt の 0n は偽であり、他の値は真です

if (0n) {
  // never executes
}

||&& などのブール演算子も、数値と同様に BigInt で動作します

alert( 1n || 2 ); // 1 (1n is considered truthy)

alert( 0n || 2 ); // 2 (0n is considered falsy)

ポリフィル

BigInt のポリフィルはトリッキーです。その理由は、+- など多くの JavaScript 演算子が、通常の数値と比較して BigInt で異なる動作をするためです。

たとえば、BigInt の除算は常に BigInt を返します (必要に応じて丸められます)。

このような動作をエミュレートするために、ポリフィルはコードを分析し、そのようなすべての演算子をその関数に置き換える必要があります。しかし、そうすることは面倒であり、多くのパフォーマンスを犠牲にします。

したがって、よく知られている優れたポリフィルはありません。

ただし、JSBI ライブラリの開発者によって別の方法が提案されています。

このライブラリは独自のメソッドを使用して大きな数を実装しています。ネイティブの BigInt の代わりに使用できます

操作 ネイティブ BigInt JSBI
数値からの作成 a = BigInt(789) a = JSBI.BigInt(789)
加算 c = a + b c = JSBI.add(a, b)
減算 c = a - b c = JSBI.subtract(a, b)

…そして、ポリフィル (Babel プラグイン) を使用して、JSBI の呼び出しを、それらをサポートするブラウザ用のネイティブ BigInt に変換します。

言い換えれば、このアプローチは、ネイティブの BigInt の代わりに JSBI でコードを記述することを提案しています。しかし、JSBI は数値を内部で BigInt のように扱い、仕様に厳密に従ってエミュレートするため、コードは「BigInt 対応」になります。

BigInt をサポートしていないエンジンに対しては、このような JSBI コードを「そのまま」使用できます。また、サポートしているエンジンに対しては、ポリフィルが呼び出しをネイティブ BigInt に変換します。

参考文献

チュートリアルマップ

コメント

コメントする前にこれを読んでください…
  • 改善のための提案がある場合は、コメントする代わりに GitHub issue を送信するか、プルリクエストを送信してください。
  • 記事の内容を理解できない場合は、詳しく説明してください。
  • コードを数語挿入するには、<code> タグを使用し、複数行の場合は <pre> タグで囲み、10 行を超える場合はサンドボックス (plnkrjsbincodepen…) を使用してください