JavaScript | 長整数リテラルで利用可能な演算子

JavaScript JavaScript
スポンサーリンク

概要

  • BigInt は桁数が非常に大きい整数を扱う型(末尾に n を付ける)。
  • 普通の Number(浮動小数)とは自動で混ざらない(混ぜるとエラーになる)。必ず明示的に変換する。

1. 作り方(BigInt の生成)

const a = 123n;         // リテラル(推奨)
const b = BigInt("9007199254740992"); // 文字列から
const c = BigInt(123);  // Number(整数ならOK)
JavaScript
  • n を付けた整数リテラルが最も簡単。
  • BigInt() に Number を渡すなら整数でないと RangeErrorになる(例:BigInt(123.3) はエラー)。

2. 算術(+ – * % ** /)── 普通に使えるが注意点あり

10n + 5n    // → 15n
10n - 3n    // → 7n
3n * 4n     // → 12n
7n % 3n     // → 1n
2n ** 10n   // → 1024n
JavaScript
  • 割り算 / は小数を返さない(商を整数に切り捨てる・ゼロに向かって切る)。例:7n / 3n2n。小数が必要なら別処理が必要。

小数が欲しいときの一例

// 精度を自分で決めて計算する(例:小数2桁)
const a = 7n, b = 3n;
const decimal2 = Number(a * 100n / b) / 100; // -> 2.33
JavaScript

(上の例は BigInt 同士で割ってから Number に変換して小数を得る手法)

3. BigInt と Number を混ぜるとエラーになる(重要)

1n + 2   // TypeError: cannot mix BigInt and other types
0 + 1n   // TypeError
JavaScript
  • 演算子に BigInt と Number を混ぜると(JS は)暗黙の変換を行わないため TypeError になる。必ず片方を明示的に変換してから演算する。

変換の例

// Number -> BigInt(整数であることを確認)
const n = 5; 
if (Number.isInteger(n)) {
  const r = BigInt(n) + 10n; // OK
}

// BigInt -> Number(精度が失われる可能性あり)
const big = 9007199254740991n;
const num = Number(big); // 失われる可能性あり(注意)
JavaScript

BigInt() は整数以外を渡すと例外になる、Number(big) は明示的な変換で失われる精度に注意、という使い分けです。

4. 単項演算子(+、−)と ++/–

  • -(単項マイナス)は BigInt に使える: -15n-15n
  • +(単項プラス)は BigInt に使えない+1n は TypeError)。
let x = 15n;
x++;    // → 16n (インクリメント OK)
--x;    // → 15n
+15n;   // TypeError: Cannot convert a BigInt value to a number
JavaScript

5. ビット演算・シフト

  • &, |, ^, ~, <<, >> は BigInt に対して使える(ビット演算の扱いは BigInt 用に定義されている)。
  • 符号なし右シフト >>> は BigInt では使えない(エラー)。
    (※ビット演算を使う際は BigInt 同士で使うこと)

例:

(5n & 3n) // -> 1n
(1n << 4n) // -> 16n
JavaScript

6. 比較(<, >, <=, >=, ==, ===)

  • <, >, <=, >= は BigInt と Number を混ぜても「数学的な値」で比較できる(3n > 2 → true)。
  • == は型変換を行うので 0n == 0true
  • === は型も比較するため 0n === 0false
54 == 54n   // true
54 === 54n  // false
3n > 2      // true
JavaScript

7. JSON / シリアライズの罠

  • JSON.stringify に BigInt を直接渡すとエラー(シリアライズできない)。そのまま送れないので、文字列に変換するか replacer を使う必要がある。

例(replacer を使う):

const obj = { id: 123n, name: "Alice" };
const json = JSON.stringify(obj, (_, v) => typeof v === "bigint" ? v.toString() : v);
// -> '{"id":"123","name":"Alice"}'
JavaScript

復元するときは BigInt(parsed.id) のように戻す必要があります。

8. よくあるハマりどころ(まとめ)

  1. Number と混ぜて計算しようとして TypeError → 明示的に変換する。
  2. 割り算で小数が切り捨てられる → 必要なら別の方式で小数を再現する(分子を拡大して計算する等)。
  3. +(単項プラス)で TypeErrorNumber(big) など明示変換を使う。
  4. JSON に突っ込めないtoString() するか replacer を使う。
  5. BigInt(浮動小数) はエラーBigInt(123.3)RangeError。整数であることを確認してから変換。

9. 実用的なヘルパー(安全に混ぜたいときの簡単な例)

// Number (整数) を安全に BigInt に変換する
function toBigIntSafe(x) {
  if (typeof x === "bigint") return x;
  if (typeof x === "number" && Number.isInteger(x)) return BigInt(x);
  throw new TypeError("toBigIntSafe: integer Number or BigInt required");
}

// BigInt演算推奨:Number を使うなら明示的に変換する
function addAsBigInt(a, b) {
  return toBigIntSafe(a) + toBigIntSafe(b);
}

// BigInt -> Number(注意:精度喪失の可能性)
function toNumberSafe(b) {
  if (typeof b !== "bigint") return b;
  const n = Number(b);
  // 必要なら安全範囲チェック
  if (Math.abs(n) > Number.MAX_SAFE_INTEGER) {
    console.warn("精度喪失の可能性あり");
  }
  return n;
}
JavaScript
  • ヘルパーで「何を許すか」を明確にしておくとコードのバグが減ります。

10. いつ BigInt を使うべきか(実務の基準)

  • Number.MAX_SAFE_INTEGER(約 9e15)を超える可能性がある整数 を扱うなら BigInt を検討。
  • お金の細かい小数計算(通貨)は BigInt より Decimal ライブラリ/整数(最小単位=セント)を用いるほうが扱いやすい(例:セント単位を BigInt にする)。
  • 小さな計算や Math 関数(Math.sqrt 等)は Number のままの方が便利(Math は BigInt を受け取らない)。
タイトルとURLをコピーしました