Back

JavaScriptでBigIntが必要になるのはどんな時か?

JavaScriptでBigIntが必要になるのはどんな時か?

JavaScriptはほとんどの数値を問題なく扱えます — 扱えなくなるまでは。APIから大きなIDを取得したら、少し間違った値が返ってきたことに気づいたり、非常に大きな整数で正確な演算を行おうとして微妙に不正確な結果を得たりしたことがあれば、すでにBigIntが解決する問題に遭遇しています。

重要なポイント

  • JavaScriptの数値はIEEE 754倍精度形式を使用しており、安全な整数の範囲は −(2⁵³ − 1) から 2⁵³ − 1 に制限されています。この範囲を超えると、値は静かに精度を失います。
  • BigIntはプリミティブ型(ES2020で導入)で、任意のサイズの整数を表現できますが、小数は扱えません。
  • 実際のユースケースには、大きな外部ID(例:Twitter Snowflake ID)の処理、64ビットWebAssembly整数、大きなカウンターやブロックチェーンデータの正確な演算などがあります。
  • BigIntは式の中でNumberと混在させることができず、Math APIでは動作せず、JSONシリアライゼーションには独自の処理が必要です。

JavaScriptの数値が越えられない限界

すべてのJavaScriptの数値はIEEE 754倍精度浮動小数点形式を使用しています。これにより、安全な整数の範囲は −(2⁵³ − 1) から 2⁵³ − 1 となり、Number.MIN_SAFE_INTEGERNumber.MAX_SAFE_INTEGERで表されます。

この境界を超えると、整数は静かに精度を失います:

console.log(9007199254740991 + 1)  // 9007199254740992 ✅
console.log(9007199254740991 + 2)  // 9007199254740992 ❌ (間違い)

// これが精度問題の実例です:
9007199254740992 === 9007199254740993 // true — JavaScriptにとっては同じ値

エラーは投げられません。値が単に間違っているだけです。これがBigIntが解決するために設計された精度限界の問題です。

BigIntとは実際に何か

BigIntはES2020で導入されたJavaScriptの組み込みプリミティブ型で、任意のサイズの整数を表現でき、利用可能なメモリによってのみ制限されます。整数リテラルにnを付けるか、BigInt()コンストラクタを使用して作成します:

const big = 9007199254740993n                 // リテラル構文
const alsoBig = BigInt("9007199254740993")    // 文字列を使ったコンストラクタ

9007199254740992n === 9007199254740993n        // false ✅ — 正しい

重要な制約が一つあります:BigIntは整数のみです。小数や分数値を表現できません。1.5nSyntaxErrorを投げます。

JavaScriptでBigIntを使うべき時

ほとんどのフロントエンドコードはBigIntを必要としません。しかし、いくつかの実際のシナリオでは本当に必要になります。

外部システムからの大きなID。 TwitterのSnowflake IDシステムや類似の分散IDスキームは、Number.MAX_SAFE_INTEGERを超える64ビット整数を生成します。REST APIがこれらをJSON数値として返すと、JavaScriptは静かにそれを破壊します。文字列として解析してBigIntに変換すると、値を正確に保持できます。

// APIから文字列として受け取った64ビットID
const userId = BigInt("922337203685477580")

WebAssemblyからの64ビット整数。 WebAssemblyのi64型はJavaScriptのBigIntに直接マッピングされます。Wasmモジュールが64ビット整数を返したり受け取ったりする場合、それらを正しく処理するためにBigIntが必要です。

精度が決して失われてはならない正確な整数演算。 特定のブロックチェーントランザクション値、大きなカウンター、または高精度タイムスタンプ演算(例:エポックからのナノ秒)は、安全な整数範囲を超える可能性があります。BigIntはすべての桁を正確に保ちます。

知っておくべき重要な制約

BigIntに手を伸ばす前に、その制限を理解してください:

BigIntとNumberを演算で混在させることはできません。 そうするとTypeErrorが投げられます。明示的な変換が必要です:

const big = 10n
const num = 5

big + num            // ❌ TypeError
big + BigInt(num)    // ✅ 15n
Number(big) + num    // ✅ 15 (ただし大きな値ではBigIntの精度を失う)

Math APIはBigIntで動作しません。 Math.max()Math.sqrt()、およびその他すべてのMathメソッドは、BigIntが渡されると投げられます。これらの操作が必要な場合は、変換する必要があり、精度のトレードオフを受け入れる必要があります。

JSONシリアライゼーションはデフォルトで失敗します。 JSON.stringify()はBigInt値でTypeErrorを投げます。シリアライゼーションを処理するには、カスタムreplacerまたはtoJSON()メソッドが必要です:

BigInt.prototype.toJSON = function () {
  return this.toString()
}

JSON.stringify({ id: 922337203685477580n }) // '{"id":"922337203685477580"}'

これはJSON出力で値を文字列に変換することに注意してください。受信側のシステムはそれに応じて処理する必要があります。また、BigInt.prototypeのような組み込みプロトタイプを変更することは、本番コードでは一般的に推奨されません。JSON.stringify()に渡すカスタムreplacer関数の方が安全な代替手段です:

const data = { id: 922337203685477580n }

JSON.stringify(data, (key, value) =>
  typeof value === "bigint" ? value.toString() : value
) // '{"id":"922337203685477580"}'

まとめ

JavaScriptにおけるBigInt対Numberは実際には競争ではありません — それぞれ異なる目的に役立ちます。Numberがうまく処理できるすべてのもの、つまりほとんどのものにはNumberを使用してください。2⁵³ − 1を超える可能性のある整数を扱っていて、正確性が譲れない場合に特にBigIntに手を伸ばしてください。それは狭いながらも重要なカテゴリーであり、BigIntはそれを正確に処理します。

よくある質問

BigIntは、Chrome、Firefox、Safari、Edgeを含むすべてのモダンブラウザでサポートされています。ただし、Internet Explorerはサポートしていません。IEをターゲットにする必要がある場合は、ネイティブBigIntに依存するのではなく、値を文字列として保持するか、大きな数値ライブラリを使用する必要があります。

はい。標準的な比較演算子(小なり、大なり、三重等号)を使用して、BigInt値を他のBigIntと比較できます。また、緩い等価性を使用してBigIntをNumberと比較することもできるため、10n == 10はtrueを返しますが、10n === 10は異なる型であるためfalseを返します。

はい。BigInt演算は、固定サイズのハードウェア命令ではなく任意精度演算を使用するため、一般的にNumber演算よりも遅くなります。ほとんどのアプリケーションでは差はわずかですが、パフォーマンスクリティカルなループやホットパスでは、ベンチマークを取り、値が安全な整数範囲内に収まる場合はNumberを優先すべきです。

Number(100n)のようにNumberコンストラクタを使用すると、100が返されます。ただし、大きな値には注意してください。BigIntがNumber.MAX_SAFE_INTEGERを超える場合、変換は静かに精度を失います。変換する前に、常に値が安全な範囲内に収まるかどうかを確認してください。

Complete picture for complete understanding

Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Check our GitHub repo and join the thousands of developers in our community.

OpenReplay