数値計算で気を付けるべきなのは値が無限大でないかどうかのチェックを忘れないこと。PHPでももちろん数値計算で無限大の値が発生する可能性はあります。
そこでここではPHPにおいて値が無限大かどうか判定する方法について紹介します。
そもそもPHPでの無限大とは・・・
無限大というのは文字通り限りのない大きな数のこと
PHPの場合だと無限大になるのは次のような値または計算をした場合です。
- floatの最大値を超えた値
- ログ(log)計算
- 累乗(pow)計算
floatの最大値を超えた時点(←ここが重要!)で無限大扱いになります。ただし整数(int)の最大値を超えた時点では無限大にならないことに要注意です。(intの最大値を超えると自動でfloatに変換される)
ログ計算・累乗計算など大きな数になりやすい計算を行った場合に発生しやすいです。
そしてPHP内で実際に定義されている無限大の値は次の2種類
- INF(正の無限大)
- -INF(負の無限大)
一言で無限大と言ってもプラス方向なのかマイナス方向なのかで異なります。
では具体的にどんな計算をすれば無限大になるのか・・
ということですが次のコードが実際に無限大になる計算例(ちなみに var_export関数 はコード内で使われるそのままの形式で値を表示する関数)
1 2 3 4 5 6 7 8 |
var_export( pow( 2, 1024 ) ); /// => INF var_export( log( 0 ) ); /// => -INF var_export( log10( 0 ) ); /// => -INF |
pow(2, 1024) つまり 2 の 1024乗 みたいなバカでかい累乗計算をしたり、 log( 0 ) のように0の対数計算をした場合、 コメントに書いた通り INF とか -INF の値になります。
こういう風に計算の結果でfloatの範囲を超えてしまったものが無限大
普通の計算ではまず出てこないですが、特殊な計算(ログとか累乗)をしたりフォームから入力を求めて計算する場合はチェックが必要になってきます。
無限大(Infinity)をチェックするには・・
では無限大をチェックする一番簡単な方法は何かというと is_infinite関数 を使うことです。
その使い方は次のように無限大になりえる値を渡すだけ
1 2 3 4 5 6 7 8 9 10 11 |
var_export( is_infinite( pow( 2, 1024 ) ) ); /// => true var_export( is_infinite( log(0) ) ); /// => true var_export( is_infinite( 2 * 1024 ) ); /// => false var_export( is_infinite( 1 / 2 / 3 ) ); /// => false |
返り値は無限大なら true 、それ以外(有限の数値)なら false を返すというシンプルな関数です。
ちなみにこれとは逆に有限かの判定するなら次のように is_finite関数 を使えばOK
1 2 3 4 5 6 7 8 9 10 11 |
var_export( is_finite( pow( 2, 1024 ) ) ); /// => false var_export( is_finite( log(0) ) ); /// => false var_export( is_finite( 2 * 1024 ) ); /// => true var_export( is_finite( 1 / 2 / 3 ) ); /// => true |
こっちは is_infinite を逆にしただけです。(つまり有限なら true 、無限大なら false が返ってくる)
まあ普通にPHPを使っているならこういう関数も滅多に使わないとは思いますが・・・
とはいっても複雑な計算処理が必要な場面が出てきたら使う可能性はあると思うので、知っておいて損はないかもしれませんね。
補足 : 非数(NAN)について
ここまで無限大を判定する方法についてまとめました。
この無限大に加え、数値計算で不正チェックをするのに欠かせない値があります。
それが非数(NAN)と呼ばれる数値以外を表す値のこと
例えば次コードのように log とかの数学関数で無効な計算が行われたときに発生します。
1 2 3 4 5 |
var_export( log( -1 ) ); /// => NAN var_export( sqrt( -4 ) ); /// => NAN |
上コードのように log(-1 ) とか sqrt(-4) みたいな数学的に不正な計算が代表的です。
そしてこのNAN判定をするときは1つ注意点があって、
次のように等号 === や == を使って比較してはいけません。
1 |
NAN === NAN |
定数同士の比較なら true が返ってきそうですが、実はNAN同士を比較すると false になります。
こういうNAN特有の性質があるのでNAN判定するときは要注意ですね。
ちなみにNANの詳しい性質や正しい判定方法は次でまとめました。
もしPHPでNANチェックする必要はあるなら上記事で書いた方法が一番確実です。
ここまでのまとめ
ということで簡単にここまで内容まとめ
- 無限大には2種類ある
正の無限大 INF あるいは負の無限大 -INF のどちらか
floatの最大値を超えたり、ログ・累乗計算などで発生することが多い - 無限大判定にはis_infinite関数を使う
チェックしたい値を渡し、無限大なら true 、それ以外なら false が返ってくる
ちなみに有限のチェックには逆バージョンの is_finite関数 も使える
以上PHPで無限大(Infinity)の値を判定する方法についてでした。