MAX_SAFE_INTEGERとMIN_SAFE_INTEGERとは?【JavaScript】

JavaScriptには扱える整数値の範囲に制限があります。

範囲内での整数演算は正確に行われますが、範囲外での整数演算は正確に行われません。

これを防ぐために、JavaScriptではMAX_SAFE_INTEGERMIN_SAFE_INTEGERというプロパティが用意されています。

この記事では、MAX_SAFE_INTEGERMIN_SAFE_INTEGERについて、以下の内容をサンプルコードを用いてわかりやすく解説します。

  • MAX_SAFE_INTEGERとは
  • MIN_SAFE_INTEGERとは
  • なぜ 2^53 - 1 が上限なのか?
  • Number.isSafeInteger()で安全な範囲を確認する
  • BigIntで大きな数値を安全に扱う

MAX_SAFE_INTEGERとは

JavaScriptのNumberオブジェクトにはMAX_SAFE_INTEGERというプロパティがあります。

MAX_SAFE_INTEGERは、JavaScriptで安全に(誤差なく)扱える最大の整数値です。MAX_SAFE_INTEGERの値は2^53 - 1、つまり9007199254740991に相当します。

console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991

MAX_SAFE_INTEGERより大きい数値を使った場合、整数演算や比較が正確に行われません。たとえば、以下のようなコードを実行してみましょう。

console.log(9007199254740991 + 1); // 9007199254740992
console.log(9007199254740991 + 2); // 9007199254740992 (誤った結果)
console.log(9007199254740991 === 9007199254740992); // false
console.log(9007199254740991 + 1 === 9007199254740991 + 2); // true (誤った結果)

本来であれば9007199254740991 + 29007199254740993になるはずですが、範囲外に達したため正確な結果が得られなくなっています。

MIN_SAFE_INTEGERとは

JavaScriptにはMAX_SAFE_INTEGERと同様に、MIN_SAFE_INTEGERも存在します。

MIN_SAFE_INTEGERは、JavaScriptで安全に(誤差なく)扱える最小の整数値です。MIN_SAFE_INTEGERの値は-(2^53 - 1)、つまり-9007199254740991に相当します。

console.log(Number.MIN_SAFE_INTEGER); // -9007199254740991

MIN_SAFE_INTEGERをより小さい数値を使った場合、整数演算や比較が正確に行われません。たとえば、以下のようなコードを実行してみましょう。

console.log(-9007199254740991 - 1); // -9007199254740992
console.log(-9007199254740991 - 2); // -9007199254740992 (誤った結果)
console.log(-9007199254740991 === -9007199254740992); // false
console.log(-9007199254740991 - 1 === -9007199254740991 - 2); // true (誤った結果)

本来であれば-9007199254740991 - 2-9007199254740993になるはずですが、範囲外に達したため正確な結果が得られなくなっています。

なぜ 2^53 - 1 が上限なのか?

MAX_SAFE_INTEGERの値が2^53 - 1MIN_SAFE_INTEGERの値が-(2^53 - 1)になっている理由は、JavaScriptの数値が倍精度浮動小数点数(IEEE 754 標準)で表現されているからです。

倍精度浮動小数点数では、全体で64ビットを使い、その内訳は次の通りです。

  • 1ビットが符号ビットに割り当てられており、正の数か負の数かを示します。
  • 11ビットが指数部に使われます。
  • 52ビットが仮数部に割り当てられており、さらに隠れた1ビットとして常に1が仮定されているため、実質的には53ビットの精度で整数を表現できます。

そのため、JavaScriptでは安全に扱える整数の範囲が-(2^53 - 1)から2^53 - 1までとなっています。

Number.isSafeInteger()で安全な範囲を確認する

JavaScriptでは、Number.isSafeInteger()を使用して、数値が安全に(誤差なく)扱える範囲内であるかどうかを確認できます。

console.log(Number.isSafeInteger(9007199254740991)); // true
console.log(Number.isSafeInteger(9007199254740992)); // false
console.log(Number.isSafeInteger(-9007199254740991)); // true
console.log(Number.isSafeInteger(-9007199254740992)); // false

この関数を使うことで、大きすぎる数値や小さすぎる数値によるエラーを防ぐことができます。

BigIntで大きな数値を安全に扱う

MAX_SAFE_INTEGERより大きな整数やMIN_SAFE_INTEGERより小さな整数を扱いたい場合は、JavaScriptのBigInt型を使用します。BigIntは、任意の大きさの整数を正確に表現できるデータ型です。

let largeNumber = BigInt(9007199254740991) + BigInt(2);
console.log(largeNumber); // 9007199254740993n

BigIntを使うことで、整数の範囲制限を気にせずに安全に大きな数値を操作できます。ただし、BigInt型と通常のNumber型の数値を直接混ぜて計算することはできないため、注意が必要です。

let num = 10;
let bigIntNum = BigInt(20);

console.log(num + bigIntNum); 

// エラー
// TypeError: Cannot mix BigInt and other types, use explicit conversions

このような場合、数値の型を揃える必要があります。

本記事のまとめ

この記事ではMAX_SAFE_INTEGERMIN_SAFE_INTEGERについて、以下の内容を説明しました。

  • MAX_SAFE_INTEGERとは
  • MIN_SAFE_INTEGERとは
  • なぜ 2^53 - 1 が上限なのか?
  • Number.isSafeInteger()で安全な範囲を確認する
  • BigIntで大きな数値を安全に扱う

お読み頂きありがとうございました。