JavaScript/Number/isSafeInteger

カテゴリ:Book:JavaScript#Number/isSafeInteger%20

Number.isSafeInteger() は、ECMAScript における Number オブジェクトのメソッドで、与えられた値が安全な整数(safe integer)であるかどうかを判定します。安全な整数とは、IEEE-754 倍精度浮動小数点形式で正確に表現できる整数のことで、Number.MIN_SAFE_INTEGER)から Number.MAX_SAFE_INTEGER)までの範囲にある整数を指します。

構文

Number.isSafeInteger(value)

パラメータ

value
安全な整数かどうかを判定する値。

戻り値

指定された値が安全な整数である場合は true、そうでない場合は false を返します。

説明

Number.isSafeInteger() メソッドは、引数が以下の条件をすべて満たす場合に true を返します:

これらの条件のいずれかに該当しない場合、メソッドは false を返します。

特性

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

  • 静的メソッド: このメソッドは Number オブジェクトのプロトタイプではなく、Number コンストラクタに直接関連付けられています。
  • ECMAScript 6: このメソッドは ECMAScript 6(ES2015)で導入されました。
  • 型変換なし: このメソッドは引数を数値に変換せず、引数が Number 型でない場合は常に false を返します。

基本的な使用法

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

// 整数値の確認
console.log(Number.isSafeInteger(3)); // true
console.log(Number.isSafeInteger(Math.pow(2, 53) - 1)); // true
console.log(Number.isSafeInteger(-Math.pow(2, 53) + 1)); // true
console.log(Number.isSafeInteger(Math.pow(2, 53))); // false

// 浮動小数点数の確認
console.log(Number.isSafeInteger(3.1)); // false
console.log(Number.isSafeInteger(3.0)); // true

// 非数値の確認
console.log(Number.isSafeInteger(NaN)); // false
console.log(Number.isSafeInteger(Infinity)); // false
console.log(Number.isSafeInteger('3')); // false
console.log(Number.isSafeInteger(null)); // false

このプログラムでは、様々な値に対して Number.isSafeInteger() メソッドを適用し、それらが安全な整数かどうかを確認しています。

Number.MAX_SAFE_INTEGER との関係

以下のプログラムは、Number.isSafeInteger()Number.MAX_SAFE_INTEGER の関係を示しています。

// 安全な整数の上限
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
console.log(Number.isSafeInteger(Number.MAX_SAFE_INTEGER)); // true

// 安全な整数の範囲を超える
console.log(Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1)); // false
console.log(Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 2)); // false

// 安全でない整数の演算の問題
console.log(Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2); // true (!) 異なる値なのに等しくなる

このプログラムでは、Number.MAX_SAFE_INTEGER までの整数は安全ですが、それを超えると安全ではなくなることを示しています。安全でない整数値を使用すると、等値比較などで予期せぬ結果が生じる可能性があります。

独自の isSafeInteger 実装

Number.isSafeInteger() メソッドが利用できない環境でも、同等の機能を実装できます。

// 独自の isSafeInteger 実装
function isSafeInteger(value) {
  return Number.isInteger(value) && 
         Math.abs(value) <= Number.MAX_SAFE_INTEGER;
}

// または ES6 未対応環境での polyfill
if (!Number.isSafeInteger) {
  Number.isSafeInteger = function(value) {
    return typeof value === 'number' && 
           Math.floor(value) === value &&
           Math.abs(value) <= 9007199254740991;
  };
}

// テスト
console.log(isSafeInteger(42)); // true
console.log(isSafeInteger(9007199254740992)); // false
console.log(isSafeInteger(3.5)); // false

このプログラムでは、Number.isSafeInteger() メソッドの独自実装と、古いブラウザ向けの polyfill の例を示しています。

実用的な例

安全な数値計算の実装

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

// 安全な整数演算を行う関数
function safeAdd(a, b) {
  if (!Number.isSafeInteger(a) || !Number.isSafeInteger(b)) {
    throw new Error('入力値が安全な整数ではありません');
  }
  
  const result = a + b;
  
  if (!Number.isSafeInteger(result)) {
    throw new Error('計算結果が安全な整数の範囲を超えています');
  }
  
  return result;
}

// 使用例
try {
  console.log(safeAdd(10, 20)); // 30
  console.log(safeAdd(Number.MAX_SAFE_INTEGER, 1)); // エラー
} catch (e) {
  console.error(e.message); // "計算結果が安全な整数の範囲を超えています"
}

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

ID の安全性チェック

以下のプログラムは、データベースから取得した ID 値が安全な整数の範囲内にあるかどうかを確認する例を示しています。

// ID の安全性をチェックするユーティリティクラス
class IDValidator {
  constructor() {
    this.warningIssued = new Set();
  }
  
  // ID が安全かどうかをチェック
  validateID(id, source) {
    const idNum = Number(id);
    
    if (!Number.isSafeInteger(idNum)) {
      const key = <code>${source}-${id}</code>;
      
      // 同じ ID について警告を繰り返さない
      if (!this.warningIssued.has(key)) {
        console.warn(<code>警告: ${source} から取得した ID ${id} は安全な整数ではありません文字列として扱ってください</code>);
        this.warningIssued.add(key);
      }
      
      return false;
    }
    
    return true;
  }
  
  // 安全に ID を処理する
  processID(id, source) {
    if (this.validateID(id, source)) {
      // 数値として処理
      return { id: Number(id), type: 'number' };
    } else {
      // 文字列として処理
      return { id: String(id), type: 'string' };
    }
  }
}

// 使用例
const validator = new IDValidator();

// 安全な ID の処理
console.log(validator.processID(123456, 'users')); // { id: 123456, type: 'number' }

// 安全でない ID の処理
const largeID = '9007199254740993'; // MAX_SAFE_INTEGER + 2
console.log(validator.processID(largeID, 'products')); // { id: "9007199254740993", type: 'string' }

このプログラムでは、外部ソースから取得した ID 値が安全な整数の範囲内にあるかをチェックし、安全でない場合は文字列として処理するユーティリティクラスの例を示しています。これにより、大きな ID 値を扱う際の精度の問題を回避することができます。

BigInt を使った安全な整数の扱い

ECMAScript 2020(ES11)で導入された BigInt 型を使用すると、Number.MAX_SAFE_INTEGER を超える整数値も安全に扱うことができます。

// Number の制限を超える値
const unsafe = Number.MAX_SAFE_INTEGER + 1;
console.log(unsafe); // 9007199254740992
console.log(Number.isSafeInteger(unsafe)); // false

// BigInt を使用した安全な大きな整数
const safeBigInt = BigInt(Number.MAX_SAFE_INTEGER) + 1n;
console.log(safeBigInt); // 9007199254740992n
console.log(safeBigInt === BigInt(Number.MAX_SAFE_INTEGER) + 2n); // false (正しい比較)

// BigInt と Number の相互変換時の注意点
function convertToBigIntIfNeeded(value) {
  if (typeof value === 'number') {
    if (!Number.isSafeInteger(value)) {
      console.warn(`警告: ${value} は安全な整数ではありません。BigInt に変換します。`);
      return BigInt(Math.floor(value));
    }
    return BigInt(value);
  }
  return value;
}

console.log(convertToBigIntIfNeeded(Number.MAX_SAFE_INTEGER)); // 9007199254740991n
console.log(convertToBigIntIfNeeded(Number.MAX_SAFE_INTEGER + 1)); // 警告を出力して 9007199254740992n

このプログラムでは、Number.isSafeInteger() を使って安全でない整数を検出し、必要に応じて BigInt 型に変換する例を示しています。BigInt を使用すると、任意の精度で整数を扱うことができます。

ブラウザの互換性

Number.isSafeInteger() メソッドは、ECMAScript 6(ES2015)で導入されたため、以下のようなモダンブラウザで利用できます:

  • Chrome 34 以降
  • Firefox 32 以降
  • Safari 10 以降
  • Edge 12 以降
  • Internet Explorer: サポートなし

古いブラウザでこのメソッドを使用する場合は、前述の polyfill を使用することができます。

関連項目

脚註

    外部リンク

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