JavaScript 速習チュートリアル

JavaScript BigInt

1. JavaScript BigInt とは?

BigInt は、巨大な整数値を扱い、保存するための JavaScript データ型(Data Type) です。

BigInt を使用することで、Number 型の限界を超える大きな整数を扱うことが可能になります。
BigInt は、利用可能なメモリが許す限り、あらゆるサイズ の整数を表現できます。

2. JavaScript における精度の限界

JavaScript の Number 型は、15 桁までしか正確に表現できません。

// 15 桁:正確
let x = 999999999999999;

// 16 桁:精度が失われる
let y = 9999999999999999;

2.1 Numbers は 64 ビット浮動小数点

JavaScript のすべての Numbers は、64 ビット浮動小数点(64-bit floating-point) 形式(IEEE 754 標準)で保存されます。

この標準では、非常に大きな数値は正確に表現できず、四捨五入(丸め)されてしまいます。

JavaScript が安全に表現できる整数は、2^53-1 (9,007,199,254,740,991) までです。

また、負の方向には -2^53-1 (-9,007,199,254,740,991) までとなります。

// 最大値 = 9007199254740991
let x = Number.MAX_SAFE_INTEGER;

// 最小値 = -9007199254740991
let y = Number.MIN_SAFE_INTEGER;

Number.MAX_SAFE_INTEGER より大きい整数は、精度を失います。

// 最大値(正確)
let x = 9007199254740991;

// 最大値 + 10(不正確)
let y = x + 10;

同様に、Number.MIN_SAFE_INTEGER より小さい整数も精度を失います。

// 最小値(正確)
let x = -9007199254740991;

// 最小値 - 10(不正確)
let y = x - 10;

注意: JavaScript には厳密な意味での「整数型(Integer)」は存在しませんでした。すべての Numbers は 64 ビット浮動小数点として扱われます。

3. BigInt の作成方法

BigInt を作成するには、主に 2 つの方法があります。

  1. 整数の末尾に n サフィックスを付ける
  2. BigInt() コンストラクタに文字列を渡す

// 整数リテラルの末尾に n を付ける:
let x = 999999999999999n;

// BigInt() コンストラクタに文字列を渡す:
let y = BigInt("999999999999999");
let x = 12345678901234567890n;
let y = BigInt("12345678901234567890");

また、BigInt() コンストラクタに Number を渡して作成することもできますが、Number は 15 桁までしか正確ではない ことに注意してください。

let x = BigInt(9999999999999999); // 注意:この時点で元の Number が精度を失っている可能性がある

4. BigInt は JavaScript のデータ型

BigInt に対して typeof を実行すると "bigint" が返されます。

let x = BigInt(999999999999999);

let type = typeof x; // "bigint"

BigInt は、JavaScript において 2 番目の数値データ型(Number に次ぐもの)です。
BigInt の登場により、JavaScript がサポートするデータ型は全部で 8 つになりました。

  1. String
  2. Number
  3. Bigint
  4. Boolean
  5. Undefined
  6. Null
  7. Symbol
  8. Object

5. 算術演算子 (Arithmetic Operators)

BigInt は標準的な JavaScript の 算術演算子 をサポートしています。
(+, -, ++, --, *, /, %, **)

例(乗算)

let x = 9007199254740995n;
let y = 9007199254740995n;

let z = x * y;

6. BigInt と Number の混在

BigInt と Number の間で直接計算を行うことは許可されていません(TypeError が発生します)。
計算を行う前に、明示的な型変換を行う必要があります。

BigInt と Number を直接混ぜることはできません:

let x = 10n;
let y = 5;

let z = x + y; // ❌ TypeError

解決するには、どちらか一方を明示的に変換します:

let x = 10n;
let y = 5;

let z = Number(x) + y;

7. BigInt と Number の変換

  • BigInt から Number への変換: Number() コンストラクタを使用します。
  • Number から BigInt への変換: BigInt() コンストラクタを使用します。

// BigInt を作成
let largeNumber = BigInt("12345678901234567890");

// 変換
let num = Number(largeNumber);

重要: 巨大な BigInt を Number に変換すると、Infinity になったり精度が失われたりする可能性があります。

8. BigInt と小数点

BigInt は小数を持つことができません。

let x = 1.5n; // ❌ TypeError

BigInt の除算の例

let x = 5n;
let y = x / 2;
// ❌ Error: BigInt と他の型を混ぜることはできません。明示的な変換が必要です。

let x = 5n;
let y = Number(x) / 2; // 2.5

また、小数点(端数)を持つ Number を BigInt に変換しようとするとエラーが発生します。

9. 比較演算子 (Comparison Operators)

BigInt は標準的な JavaScript の 比較演算子 をサポートしています。
(<, >, ==, ===, !=, !==, <=, >=)

また、BigInt と Number を比較することも可能です。

比較は通常通り機能します:

// true
let x = (10n > 5n);

// false (データ型が異なるため)
let y = (10n === 10);

// true (抽象比較 / 緩い比較)
let z = (10n == 10);

厳密等価演算子 (===) を使用した場合、BigInt と Number は型が異なるため、値が同じでも常に false となります。

10. ビット演算子 (Bitwise Operators)

BigInt はビット演算をサポートしていますが、BigInt 同士に限られます(Number との演算は不可)。

  • & (AND)
  • | (OR)
  • ^ (XOR)
  • ~ (NOT)

let a = 5n; // 0101
let b = 3n; // 0011

let x = (a & b); // 1n (0001)
let y = (a | b); // 7n (0111)
let z = (a ^ b); // 6n (0110)
let n = (~a);    // -6n

11. ビットシフト演算子

BigInt は、以下の 2 つのシフト演算子のみをサポートしています。

  • << (左シフト)
  • >> (符号あり右シフト)

let big = 10n; // バイナリ: 1010

let x = (big << 2n); // 40n (101000)
let y = (big >> 1n); // 5n (0101)

11.1 重要なルール

  • 両方のオペランドが BigInt である必要があります。
  • シフト量は非負(0以上)である必要があります。
  • 右シフトは負の値の符号ビットを維持します。
  • 符号なし右シフト (>>>) は BigInt では使用できません。

12. BigInt の 16 進数、8 進数、2 進数表記

BigInt は、16 進数、8 進数、2 進数表記で記述することも可能です。
Number と同様に、以下の基数をサポートしています:

  • 通常(10進数):256n
  • 8 進数:0o400n
  • 16 進数:0x100n
  • 2 進数:0b100000000n

let num = 256n;
let oct = 0o400n;
let hex = 0x100n;
let bin = 0b100000000n;
let hex = 0x20000000000003n;
let oct = 0o400000000000000003n;
let bin = 0b100000000000000000000000000000000000000000000000000011n;

13. 精度の興味深い挙動

JavaScript における安全な整数の最大値は 9007199254740991 です。
これを超えた場合の「丸め」は、プログラムのセキュリティを損なう可能性があります。

MAX_SAFE_INTEGER の例

// Number の場合:精度不足により true になってしまう!
9007199254740992 === 9007199254740993; // true

// BigInt の場合:正しく false と判定される
9007199254740992n === 9007199254740993n; // false

14. まとめ

  • BigInt は 任意精度の整数 を扱えます。
  • BigInt の数値は、メモリが許す限り 大きく(あるいは小さく)できます。
  • BigInt は非常に大きな整数(暗号化、ID、タイムスタンプなど)に使用されます。
  • BigInt は 小数点(デシマル)には適していません。整数のみを扱います。
  • Math.sqrt() などの Math 関数 は BigInt では動作しません。
  • JSON.stringify() は BigInt を処理できず、エラーをスローします。

15. ブラウザの対応状況

BigInt()ES2020 の機能です。
ES2020 は、2020年9月以降、すべてのモダンブラウザでフルサポートされています。

Chrome 85Edge 85Firefox 79Safari 14Opera 71
2020年8月2020年8月2020年3月2020年9月2020年9月