JavaScript/Number/MAX SAFE INTEGER

カテゴリ:Book:JavaScript#Number/MAX%20SAFE%20INTEGER%20

Number.MAX_SAFE_INTEGER は、ECMAScript における Number オブジェクトのプロパティで、JavaScript で正確に表現および比較できる最大の整数値を表します。この値は で、9007199254740991(9,007,199,254,740,991)に等しくなります[1]

構文

Number.MAX_SAFE_INTEGER

Number.MAX_SAFE_INTEGER の値は 9007199254740991(9,007,199,254,740,991)で、 に等しくなります。

特性

Number.MAX_SAFE_INTEGER には、以下のような特性があります:

  • 読み取り専用: このプロパティは変更できません。プロパティ属性は { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false } に設定されています。
  • データプロパティ: Number.MAX_SAFE_INTEGER は値プロパティであり、メソッドではありません。
  • 安全な整数: この値までの整数は JavaScript において正確に表現および比較できます。これを超える整数値は精度が失われる可能性があります。
  • ECMAScript 6: このプロパティは ECMAScript 6(ES2015)で導入されました。

基本的な使用法

以下のプログラムは、Number.MAX_SAFE_INTEGER の基本的な使用法を示しています。

// Number.MAX_SAFE_INTEGER の値を表示
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991

// 数学的に同等な表現
console.log(Math.pow(2, 53) - 1); // 9007199254740991

// 型の確認
console.log(typeof Number.MAX_SAFE_INTEGER); // number

このプログラムでは、Number.MAX_SAFE_INTEGER の値とその型を示しています。また、この値が に等しいことも確認できます。

安全な整数の範囲

以下のプログラムは、安全な整数の範囲を超えた場合の精度の問題を示しています。

// 安全な整数の範囲内
const safeInteger = Number.MAX_SAFE_INTEGER;
console.log(safeInteger); // 9007199254740991
console.log(safeInteger + 0 === safeInteger); // true

// 安全な整数の範囲を超える
const unsafeInteger = Number.MAX_SAFE_INTEGER + 1;
const nextUnsafeInteger = Number.MAX_SAFE_INTEGER + 2;

console.log(unsafeInteger); // 9007199254740992
console.log(nextUnsafeInteger); // 9007199254740992
console.log(unsafeInteger === nextUnsafeInteger); // true (!) 異なる値なのに等しくなる

// 精度の問題
console.log(Number.MAX_SAFE_INTEGER + 3); // 9007199254740994
console.log(Number.MAX_SAFE_INTEGER + 4); // 9007199254740996
console.log(Number.MAX_SAFE_INTEGER + 5); // 9007199254740996 (!) 期待値は 9007199254740996 だが、精度の問題で同じになる

このプログラムでは、Number.MAX_SAFE_INTEGER を超える整数値を扱う際に発生する精度の問題を示しています。具体的には、異なる値が等しくなったり、予期せぬ結果になったりする例を示しています。

Number.isSafeInteger の使用

以下のプログラムは、Number.isSafeInteger メソッドを使用して、整数が安全な範囲内にあるかどうかを確認する例を示しています。

// 安全な整数かどうかの確認
console.log(Number.isSafeInteger(42)); // true
console.log(Number.isSafeInteger(Number.MAX_SAFE_INTEGER)); // true
console.log(Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1)); // false
console.log(Number.isSafeInteger(Math.pow(2, 53))); // false

// 浮動小数点数や大きな値の場合
console.log(Number.isSafeInteger(3.14)); // false
console.log(Number.isSafeInteger(Number.MAX_VALUE)); // false
console.log(Number.isSafeInteger(Infinity)); // false

このプログラムでは、Number.isSafeInteger メソッドを使用して、様々な値が安全な整数かどうかを確認する例を示しています。Number.MAX_SAFE_INTEGER 以下の整数は安全ですが、それを超える値や浮動小数点数は安全でないことがわかります。

実用的な例

整数の安全性チェック

以下のプログラムは、整数計算の結果が安全な範囲内にあるかどうかをチェックする例を示しています。

// 安全な整数計算を行う関数
function safeIntegerOperation(a, b, operation) {
  // 入力値が安全な整数かをチェック
  if (!Number.isSafeInteger(a) || !Number.isSafeInteger(b)) {
    throw new Error('入力値が安全な整数ではありません');
  }
  
  // 計算を実行
  let result;
  switch (operation) {
    case 'add':
      result = a + b;
      break;
    case 'subtract':
      result = a - b;
      break;
    case 'multiply':
      result = a * b;
      break;
    case 'divide':
      result = Math.floor(a / b); // 整数除算
      break;
    default:
      throw new Error('未対応の操作です');
  }
  
  // 結果が安全な整数かをチェック
  if (!Number.isSafeInteger(result)) {
    throw new Error('計算結果が安全な整数の範囲を超えています');
  }
  
  return result;
}

// 安全な計算
try {
  console.log(safeIntegerOperation(1000000, 2000000, 'add')); // 3000000
  console.log(safeIntegerOperation(1000000, 2000000, 'multiply')); // 2000000000000
} catch (e) {
  console.error(e.message);
}

// 安全でない計算
try {
  console.log(safeIntegerOperation(Number.MAX_SAFE_INTEGER, 1, 'add')); // エラー
} catch (e) {
  console.error(e.message); // "計算結果が安全な整数の範囲を超えています"
}

このプログラムでは、整数計算を行う前に入力値が安全な整数かをチェックし、計算結果も安全な整数の範囲内にあるかをチェックする関数の例を示しています。結果が安全な範囲を超える場合はエラーをスローします。

大きな整数のIDの扱い

以下のプログラムは、データベースなどで使用される大きな整数 ID を扱う際の注意点を示しています。

// 大きな整数 ID を文字列として扱う例
class SafeIDHandler {
  constructor() {
    this.ids = new Map();
  }
  
  // ID を追加(文字列として保存)
  addID(id) {
    const idStr = String(id);
    
    // ID が数値として安全でない場合は警告
    if (!isNaN(id) && !Number.isSafeInteger(Number(id))) {
      console.warn(<code>ID ${id} は安全な整数の範囲を超えています文字列として扱います</code>);
    }
    
    this.ids.set(idStr, { timestamp: Date.now() });
    return idStr;
  }
  
  // ID を取得
  getID(id) {
    const idStr = String(id);
    return this.ids.get(idStr);
  }
}

const handler = new SafeIDHandler();

// 安全な範囲内の ID
handler.addID(123456789);

// 安全な範囲を超える ID(例: データベースの大きな ID)
const bigID = 9007199254740993;
handler.addID(bigID);

// 取得(両方とも正しく動作)
console.log(handler.getID(123456789)); // { timestamp: ... }
console.log(handler.getID(9007199254740993)); // { timestamp: ... }

このプログラムでは、大きな整数 ID を扱う際に、安全な整数の範囲を超える値を文字列として処理する例を示しています。これにより、精度の問題を回避することができます。

BigInt との関係

ECMAScript 2020(ES11)で導入された BigInt 型は、Number.MAX_SAFE_INTEGER を超える安全な整数値を扱うための解決策です。

// Number の制限
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
console.log(Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2); // true (精度の問題)

// BigInt を使用する例
const maxSafeInteger = BigInt(Number.MAX_SAFE_INTEGER);
console.log(maxSafeInteger); // 9007199254740991n

// BigInt での計算(精度の問題なし)
console.log(maxSafeInteger + 1n); // 9007199254740992n
console.log(maxSafeInteger + 2n); // 9007199254740993n
console.log(maxSafeInteger + 1n === maxSafeInteger + 2n); // false (正しい比較)

// 非常に大きな値でも正確に計算可能
const bigValue = maxSafeInteger * maxSafeInteger;
console.log(bigValue); // 81129638414606663681390495662081n

このプログラムでは、Number.MAX_SAFE_INTEGER の制限と、BigInt を使用してこの制限を克服する例を示しています。BigInt を使用すると、任意の精度で整数を扱うことができます。

Number.MAX_SAFE_INTEGER と Number.MAX_VALUE の違い

Number.MAX_SAFE_INTEGERNumber.MAX_VALUE は以下の点で異なります:

// MAX_SAFE_INTEGER と MAX_VALUE の比較
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
console.log(Number.MAX_VALUE); // 1.7976931348623157e+308

// MAX_SAFE_INTEGER を超える整数は精度が失われる
console.log(Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2); // true

// MAX_VALUE を超える値は Infinity になる
console.log(Number.MAX_VALUE * 2); // Infinity

// MAX_SAFE_INTEGER は MAX_VALUE より小さい
console.log(Number.MAX_SAFE_INTEGER < Number.MAX_VALUE); // true

このプログラムでは、Number.MAX_SAFE_INTEGERNumber.MAX_VALUE の違いと、それぞれの制限を超えた場合の挙動を示しています。

その他の Number オブジェクトの特殊値

ECMAScript は、Number オブジェクトに他の特殊な値も定義しています:

脚註

  1. Number.MAX_SAFE_INTEGER よりも大きな整数は JavaScript では正確に表現できず、丸め誤差が発生する可能性があります。

外部リンク

カテゴリ:Book:JavaScript#Number/MAX%20SAFE%20INTEGER%20 カテゴリ:JavaScript
カテゴリ:Book:JavaScript カテゴリ:JavaScript カテゴリ:Pages using the JsonConfig extension