[PHP]is_real関数完全ガイド – 実数判定の基本から応用テクニックまで

PHP

PHPで数値処理を行う際、「この値は実数(浮動小数点数)なの?」という判定が必要になることがあります。そんな時に役立つのがis_real関数です。この記事では、is_real関数の基本的な使い方から実践的な活用方法まで、初心者にも分かりやすく解説します。

is_real関数とは?

is_real関数は、指定された変数が実数(浮動小数点数)であるかどうかを判定するPHPの組み込み関数です。is_float関数のエイリアスとして機能し、数値データの型チェックに使用されます。

基本的な構文

bool is_real(mixed $value)

パラメータ:

  • $value:チェックしたい値

戻り値:

  • true:値が実数(浮動小数点数)の場合
  • false:値が実数以外の場合

基本的な使用例

シンプルな実数チェック

<?php
// 実数の例
$float1 = 3.14;
$float2 = 2.5;
$float3 = 0.0;

// 実数以外の例
$int = 42;
$string = "3.14";
$array = [1, 2, 3];

// is_real関数でチェック
var_dump(is_real($float1));  // bool(true)
var_dump(is_real($float2));  // bool(true)
var_dump(is_real($float3));  // bool(true)
var_dump(is_real($int));     // bool(false)
var_dump(is_real($string));  // bool(false)
var_dump(is_real($array));   // bool(false)
?>

関数での実数判定

<?php
function checkNumberType($value) {
    if (is_real($value)) {
        echo "'{$value}' は実数です\n";
    } else {
        echo "'{$value}' は実数ではありません\n";
    }
}

checkNumberType(3.14);    // '3.14' は実数です
checkNumberType(42);      // '42' は実数ではありません
checkNumberType("3.14");  // '3.14' は実数ではありません
?>

is_real vs is_float – 違いはあるの?

実は、is_real関数とis_float関数は完全に同じ機能を持っています。is_realはis_floatのエイリアスとして定義されているため、どちらを使っても結果は同じです。

<?php
$number = 3.14;

// 以下は全て同じ結果
var_dump(is_real($number));   // bool(true)
var_dump(is_float($number));  // bool(true)
var_dump(is_double($number)); // bool(true) - これもエイリアス

// 一般的にはis_float()の使用が推奨される
?>

実践的な活用シーン

1. 数値入力の検証

<?php
function validatePrice($price) {
    if (!is_real($price)) {
        throw new InvalidArgumentException("価格は実数で入力してください");
    }
    
    if ($price < 0) {
        throw new InvalidArgumentException("価格は0以上で入力してください");
    }
    
    return $price;
}

try {
    $validPrice = validatePrice(99.99);
    echo "有効な価格: {$validPrice}\n";
    
    $invalidPrice = validatePrice("invalid");
} catch (InvalidArgumentException $e) {
    echo "エラー: " . $e->getMessage() . "\n";
}
?>

2. 配列内の実数フィルタリング

<?php
function filterRealNumbers($array) {
    return array_filter($array, 'is_real');
}

$mixedArray = [1, 2.5, "3.14", 4.0, true, null, 7.25];
$realNumbers = filterRealNumbers($mixedArray);

echo "元の配列: ";
print_r($mixedArray);

echo "実数のみ: ";
print_r($realNumbers);
// 結果: Array ( [1] => 2.5 [3] => 4.0 [6] => 7.25 )
?>

3. 数値処理クラスでの型チェック

<?php
class Calculator {
    public function divide($dividend, $divisor) {
        // 両方の値が数値であることを確認
        if (!is_numeric($dividend) || !is_numeric($divisor)) {
            throw new InvalidArgumentException("引数は数値である必要があります");
        }
        
        if ($divisor == 0) {
            throw new DivisionByZeroError("0で割ることはできません");
        }
        
        $result = $dividend / $divisor;
        
        // 結果が実数かどうかをチェック
        if (is_real($result)) {
            return round($result, 2); // 小数点以下2桁に丸める
        }
        
        return $result;
    }
}

$calc = new Calculator();
try {
    echo $calc->divide(10, 3) . "\n";    // 3.33
    echo $calc->divide(10, 2) . "\n";    // 5
    echo $calc->divide(10, 0) . "\n";    // エラー
} catch (Exception $e) {
    echo "エラー: " . $e->getMessage() . "\n";
}
?>

他の数値チェック関数との比較

包括的な数値チェック関数

<?php
function analyzeValue($value) {
    echo "値: " . var_export($value, true) . "\n";
    echo "is_real(): " . (is_real($value) ? 'true' : 'false') . "\n";
    echo "is_int(): " . (is_int($value) ? 'true' : 'false') . "\n";
    echo "is_numeric(): " . (is_numeric($value) ? 'true' : 'false') . "\n";
    echo "is_finite(): " . (is_finite($value) ? 'true' : 'false') . "\n";
    echo "is_infinite(): " . (is_infinite($value) ? 'true' : 'false') . "\n";
    echo "is_nan(): " . (is_nan($value) ? 'true' : 'false') . "\n";
    echo "---\n";
}

// 様々な値でテスト
analyzeValue(3.14);        // 通常の実数
analyzeValue(42);          // 整数
analyzeValue("3.14");      // 数値文字列
analyzeValue(INF);         // 無限大
analyzeValue(NAN);         // NaN (Not a Number)
analyzeValue(0.0);         // ゼロの実数
?>

実数と整数の区別

<?php
function categorizeNumber($value) {
    if (is_real($value)) {
        return "実数";
    } elseif (is_int($value)) {
        return "整数";
    } elseif (is_numeric($value)) {
        return "数値文字列";
    } else {
        return "数値以外";
    }
}

$values = [3.14, 42, "3.14", "42", true, null, "abc"];

foreach ($values as $value) {
    echo var_export($value, true) . " => " . categorizeNumber($value) . "\n";
}
?>

特殊な数値の扱い

無限大とNaNの処理

<?php
function handleSpecialNumbers($value) {
    if (!is_real($value)) {
        return "実数ではありません";
    }
    
    if (is_infinite($value)) {
        return $value > 0 ? "正の無限大" : "負の無限大";
    }
    
    if (is_nan($value)) {
        return "NaN (Not a Number)";
    }
    
    return "通常の実数: {$value}";
}

// テスト
echo handleSpecialNumbers(3.14) . "\n";        // 通常の実数: 3.14
echo handleSpecialNumbers(INF) . "\n";         // 正の無限大
echo handleSpecialNumbers(-INF) . "\n";        // 負の無限大
echo handleSpecialNumbers(NAN) . "\n";         // NaN (Not a Number)
echo handleSpecialNumbers(42) . "\n";          // 実数ではありません
?>

精度の問題と対策

<?php
function compareFloats($a, $b, $precision = 0.0001) {
    if (!is_real($a) || !is_real($b)) {
        throw new InvalidArgumentException("比較対象は実数である必要があります");
    }
    
    return abs($a - $b) < $precision;
}

// 浮動小数点数の精度問題の例
$result = 0.1 + 0.2;
echo "0.1 + 0.2 = " . $result . "\n";                    // 0.30000000000000004
echo "結果は0.3と等しい? " . ($result == 0.3 ? 'Yes' : 'No') . "\n"; // No

// 精度を考慮した比較
echo "精度を考慮した比較: " . (compareFloats($result, 0.3) ? 'Yes' : 'No') . "\n"; // Yes
?>

パフォーマンスとベストプラクティス

効率的な数値チェック

<?php
class NumberValidator {
    private $cache = [];
    
    public function isRealCached($value) {
        $key = serialize($value);
        if (!isset($this->cache[$key])) {
            $this->cache[$key] = is_real($value);
        }
        return $this->cache[$key];
    }
    
    public function validateNumberArray($numbers) {
        $valid = [];
        $invalid = [];
        
        foreach ($numbers as $index => $number) {
            if ($this->isRealCached($number)) {
                $valid[$index] = $number;
            } else {
                $invalid[$index] = $number;
            }
        }
        
        return ['valid' => $valid, 'invalid' => $invalid];
    }
}

$validator = new NumberValidator();
$numbers = [1.5, 2, "3.14", 4.0, true, null, 7.25];
$result = $validator->validateNumberArray($numbers);

echo "有効な実数: ";
print_r($result['valid']);
echo "無効な値: ";
print_r($result['invalid']);
?>

実用的な応用例

統計計算での活用

<?php
class Statistics {
    private $data = [];
    
    public function addValue($value) {
        if (!is_real($value)) {
            throw new InvalidArgumentException("統計データは実数である必要があります");
        }
        $this->data[] = $value;
    }
    
    public function mean() {
        if (empty($this->data)) {
            return 0;
        }
        return array_sum($this->data) / count($this->data);
    }
    
    public function variance() {
        if (count($this->data) < 2) {
            return 0;
        }
        
        $mean = $this->mean();
        $sum = 0;
        
        foreach ($this->data as $value) {
            $sum += pow($value - $mean, 2);
        }
        
        return $sum / (count($this->data) - 1);
    }
    
    public function standardDeviation() {
        return sqrt($this->variance());
    }
}

$stats = new Statistics();
try {
    $stats->addValue(1.5);
    $stats->addValue(2.3);
    $stats->addValue(3.7);
    $stats->addValue(4.1);
    $stats->addValue(5.2);
    
    echo "平均: " . round($stats->mean(), 2) . "\n";
    echo "分散: " . round($stats->variance(), 2) . "\n";
    echo "標準偏差: " . round($stats->standardDeviation(), 2) . "\n";
    
} catch (InvalidArgumentException $e) {
    echo "エラー: " . $e->getMessage() . "\n";
}
?>

注意点とトラブルシューティング

よくある間違い

<?php
// 間違い1: 文字列の数値をチェック
$stringNumber = "3.14";
if (is_real($stringNumber)) {
    echo "実数です";  // 実行されない
} else {
    echo "実数ではありません";  // これが実行される
}

// 正しい方法: 型変換してからチェック
$convertedNumber = (float)$stringNumber;
if (is_real($convertedNumber)) {
    echo "変換後は実数です";  // これが実行される
}

// 間違い2: ゼロ除算の結果をチェック
$result = 1 / 0;  // INF
if (is_real($result)) {
    echo "実数です";  // これは実行される(INFも実数型)
}

// 正しい方法: 有限数かどうかもチェック
if (is_real($result) && is_finite($result)) {
    echo "有限な実数です";
} else {
    echo "無限大またはNaNです";
}
?>

デバッグ用の詳細チェック関数

<?php
function debugNumberType($value) {
    echo "値: " . var_export($value, true) . "\n";
    echo "型: " . gettype($value) . "\n";
    echo "is_real: " . (is_real($value) ? 'true' : 'false') . "\n";
    echo "is_float: " . (is_float($value) ? 'true' : 'false') . "\n";
    echo "is_int: " . (is_int($value) ? 'true' : 'false') . "\n";
    echo "is_numeric: " . (is_numeric($value) ? 'true' : 'false') . "\n";
    
    if (is_real($value)) {
        echo "is_finite: " . (is_finite($value) ? 'true' : 'false') . "\n";
        echo "is_infinite: " . (is_infinite($value) ? 'true' : 'false') . "\n";
        echo "is_nan: " . (is_nan($value) ? 'true' : 'false') . "\n";
    }
    echo "---\n";
}

// 様々な値でテスト
debugNumberType(3.14);
debugNumberType(42);
debugNumberType("3.14");
debugNumberType(INF);
debugNumberType(NAN);
?>

まとめ

is_real関数は、PHPで実数(浮動小数点数)の判定を行うための便利な関数です。is_floatのエイリアスとして機能し、数値処理やデータ検証において重要な役割を果たします。

重要なポイント:

  • is_real関数は実数型の値のみをtrueと判定
  • 文字列の数値や整数はfalseを返す
  • 無限大やNaNも実数型として扱われる
  • 精度の問題を考慮した比較が必要な場合がある

適切な使用方法を理解し、他の数値チェック関数と組み合わせることで、堅牢な数値処理システムを構築できます。この記事で紹介した例を参考に、あなたのプロジェクトでもis_real関数を効果的に活用してみてください。


この記事がPHP開発の参考になれば幸いです。他にも疑問点があれば、コメントやお問い合わせフォームからお気軽にご質問ください。

タイトルとURLをコピーしました