PHP の型について調べていたら NAN
に関する記述を見つけて、これは何?と思ったので調査。
PHP: Floating point numbers - Manual
※なお、このエントリ内の PHP ソースコードの実行は、PHP 8.0.3
を使っています。
NaN とは
Not a Number
の略です。浮動小数点計算の技術標準 IEEE 754 にて仕様が定められています。PHP も typically uses the IEEE 754 double precision format
と書かれています。typically
が気になるところではあります。
PHPマニュアルにおける NaN
の記載は、以下の通り。
NaN
Some numeric operations can result in a value represented by the constant NAN. This result represents an undefined or unrepresentable value in floating-point calculations. Any loose or strict comparisons of this value against any other value, including itself, but except true, will have a result of false.Because NAN represents any number of different values, NAN should not be compared to other values, including itself, and instead should be checked for using is_nan().
浮動小数点数計算における未定義、表現不可能を表すと書いてあります。NaN
に対する比較は、true
との比較以外は false
を返すとなっています。
試してみると、厳密比較は false
でしたが緩やかな比較では true
となりました。良し悪しはおいておいて、そういう仕様ということです。
1 | php > var_dump(NAN == true); |
NaN を出力するコード
今までの PHP プログラマー人生では一度も使ったことがなかったです。JavaScript の NaN
は有名ですが、PHP の NaN
は今回が初見です。というわけで、いくつか NaN
を出力するサンプルコードを書いてみました。
1 | php > var_dump(sqrt(-1)); |
NaN の使いどころ
用途としては、浮動小数点計算を行った際に、計算結果が表現不能になっていないか?など検査するときでしょうか?is_nan
という検査メソッドも用意されているので、次のような利用方法が考えられそうです。
1 |
|
まとめ
浮動小数点計算における未定義、計算不可能を表すのが NaN
ということがよくわかりました。あまりこの手の処理をやったことがないので知らなかったのですが、数学の分野であったり、研究結果の計算などではよく使うのかもしれません。仕事として NaN
を意識することが今後あるのか…は、よく分からないですが、知っておくと役に立つ知識であることは間違いないです。
最初は桁溢れの表現かなと勘違いしていましたが、それは INF
という定数が用意されていました。is_infinite
という検査メソッドも存在しています。
おまけ
この計算は、どう NaN の?
四則演算
1 | php > var_dump(NAN + NAN); |
NAN / NAN
は NAN
なのに、NAN % NAN
は0除算で怒られる…。
Bit演算
1 | php > var_dump(NAN & NAN); |
NaN
を出す PHP のソースコード
いっぱいあったのですが、 対数計算のソースコードを選んで見ました。対数の定義では底は1でない整数
です。実際にソースコードにおいても底が1の場合は、計算不能を表す ZEND_NAN
を返すようになっています。
https://github.com/php/php-src/blob/master/ext/standard/math.c#L571-L604
1 | PHP_FUNCTION(log) |
PHPで実行してみた結果
1 | php > var_dump(log(1,1)); |