PHPでデータが非数(NAN)かどうか調べる確実な方法

PHPに限らず 非数NAN  ) は数値でないこと表すために用意された特別な数値のこと

ちょうど null  はデータがないことを表す値なのでそれと似たような感じです。

ここではデータがその非数(NAN)かどうかを判定する方法についてまとめてみました。

NANとはそもそも何なのか

NANとは何なのか・・・(「NAN」と「何」がかかってる)

お決まりのつまらないギャグを言ったところで真面目に解説します(笑)

 

これは 「Not a number」 の略で数値でないことを表すfloat型の値のことです。float型として定義されているのでNAN自体は数値であることに注意

そしてこのNANが発生するのは数学関数などで無効な計算結果が出た場合です。

例えば次がコード内でNANが出てしまう無効な計算例(ちなみに var_export関数 はコード内で使われるそのままの形式で値を表示する関数)

log( -1 )  とか sqrt( -4)  とか acos( 1.5 )  とかの数学関数で計算できない値、あるいは INF - INF  みたいな無限大を使った計算、 NAN * NAN  みたいにNAN自身を使った計算でも発生します。

 

こういう風に無効な計算で返されるのが NAN  という値

NAN自体は数として意味を持ちませんが、数学的な関数・処理で予期せぬ計算が発生したときに処理しやすくするために用意されています。

NAN同士を等号で比較するのはNG!

NANを扱う時、特に比較する場合は1つ注意点があります。

それはNAN同士を等号( == や === )で比較してはいけない、ということ

 

例えば次のようなコードを実行してみればその意味が分かるはずです。

定数同士を比較しているなら true  が返ってくると思ってしまいがちですが、なんとこのコードはNAN同士を比較しているにも関わらず false  を返してきます。

これはNANが「どんなものとも(NANとさえも)等しくならない値」と定義されているためです。

 

なので次のコード例のように等号 === でNAN判定をするのは絶対にNG

コメント内にも書いたようにこういう比較をすると全て false  が返ってきてしまいます。なのでNANかどうかを判定するには絶対に ===  を使わないように要注意!

NAN判定をする正しい方法

ではPHPでNANかどうかを判定するにはどうすればいいのか・・・

という話ですが、単純に is_nan関数 を使えばいいだけです。

この関数の使い方は簡単で判定したい値を渡すだけ

is_nan( sqrt( -4 )  みたいに渡された値が非数なら true  、逆に is_nan( 3.141519 )  みたいに数値なら false  が返ってくるので簡単に非数判定することができます。

 

こういう風にNAN判定をするなら必ず is_nan関数 を使うことが必要です。

知っていればどうってことないですが、知らないと等号で比較してしまいがちなので気を付けたいですね。

補足 : 無限大(Infinity)について

ここまででNANの性質とか判定方法について紹介してきました。

等号を使わず is_nan関数 を使用するのが正しいチェックを行うのに重要です。

 

そしてこれに加えて無限大INF)も数値の不正チェックでよく使われます。

文字通りfloat型の範囲を超えた場合に数学関数や式から返される値です。

こちらの判定チェックについては次記事で解説しました。

もし無限大になりえる値をチェックする場合はこちらの方法も知っておいて損はありません。

ここまでのまとめ

ということで簡単にここまでの内容まとめ

  • 非数(NAN)について
    数学関数( log 、 sqrt 、など...)で無効な計算が起きた場合に返される特別な数値
  • 等号でNAN比較してはダメ!
    常に異なる値を表すので NAN === NAN  と比較すると false  が返ってきてしまう
    なので値のNAN判定をするときは"絶対"に ===  を使わないように要注意!
  • is_nan関数を使うのがベスト
    例えば is_nan( log(-1) )  のように is_nan関数 をNAN判定に使うのが確実
    返り値は非数の場合は true  、数値だった場合は false  が返ってくる

間違っても NAN === NAN  みたいに等号で比較しないように気を付けましょう。この注意事項はPHP以外の言語でも大体当てはまります。

以上PHPで値が非数(NAN)かどうかを判定する方法についてでした。