2011年1月5日水曜日

プログラミング言語PHPは小数点が苦手

このエントリーをはてなブックマークに追加
Pocket

世の中には数字が苦手なヤツが3種類いる。一つは計算が遅いヤツ。一つは計算を間違えるヤツ。そして計算が終わらないヤツがいる。PHPは計算が遅いヤツだと思われていたが、それは誤解だったようだ。

計算機のプログラミング言語で、計算が遅いとか、間違えるとか、終わらないとか理解できないかも知れないが、実際にはそういう事は発生する。これは事実だ。Ubuntu Linux上のPHP 5.3.1と5.3.2-1で現象が確認されている。無限ループしているのか、以下のコードの実行すると、応答がなくなる(Exploring Binary)。

<?php $d = '2.2250738585072011e-308'; echo $d + 0; ?>

文字列を浮動小数点に変換する部分に何らかの不具合があると予想されている。10進数の2.2250738585072011e-308は、16進数の0x0.fffffffffffffp-1022に正しく丸めて変換可能な5つの17桁の数字のうちの1つで、5つの中で最大の値になる。つまり境界値になるため、境界値テストが不十分であったと言える。

既にPHPの開発者には通知済みだそうで、恐らく次のFixでは訂正されると思う。試した限りでは、gcc 4.4.3、Java 1.6.0_20、Perl 5.10.1、Python 3.1.3、R 2.11.1で同様のコードを実行すると、丸め誤差は発生するものの同様の問題は起きない。海外のソーシャル・ブックマーク・サイトのredditでは、この話題で盛り上がっており、PHPではなくgccの浮動小数点のバグだという指摘や、デバッガでPHPの動作を追いかけた報告があがっている。なお、「2010年になるまで気づかなかったのだから、大きな問題ではない」とコメントすると、数字に弱いからPHPを利用していると思われるので、発言には気をつけた方が良いようだ。

PHPはウェブ・アプリケーション構築で人気のプログラミング言語で、特にインターネットの不特定多数向けに利用が多い。Yahoo!Japanや楽天、gooなどでも採用されている。数値演算などで使われる事はまずないので、この問題に気づく人もいなかったのだろう。今回のバグ発見は、15年の歴史があって広く使われるようになっても、ソフトウェアが完成に至るのは難しい事を示している。

0 コメント:

コメントを投稿