PHPのround関数について、ネット上で次のような記述を見つけました。







各言語を面白おかしく紹介する内容とはいえ、ずいぶん雑な理解だなーという印象です。ゆるふわな話だけでPHPがdisられ続けるのもどうかと思うので、一連のround関数の話題について僕なりの総括をしてみたいと思います。

以下、こんなあらすじで紹介していきます。





PHP以外でも四捨五入関数のバグっぽい挙動は珍しくない RubyやPythonの四捨五入はエッジケースで間違っていた Javaの四捨五入にはバグなのか仕様なのか微妙なエッジケースがJava 7まで存在していた 四捨五入で小数点以下n位に丸める仕様がそもそも難しい

PHPの現在の実装は整数への丸めについては他の言語と同じ 当時話題になったround関数の実装は2009年リリースのPHP 5.3.0でリプレース済



経緯など 元ネタを知らない人向けに経緯を紹介します。

僕が2007年にPHPソースコード中の四捨五入関数の実装に気持ち悪いマジックナンバーを見つけて「PHPの奇妙なround関数」という記事にしたところ、なぜかRubyのまつもとさんの日記に拾われてバズったという事件がありました。

問題になったround関数の実装は率直に言ってやっつけ感あふれるもので、disられても仕方ない内容だったと思います。そもそも僕自身も「PHP気持ち悪いよね、ひどいよね」というつもりで記事を書いたわけです。しかし、非PHPユーザーが安全地帯からPHPを叩くためだけに乗っかってくるのに若干イラっとしたので、「お前らが安全地帯だと思ってる土台も実は脆いんだぜ」と言いたいがために他言語の浮動小数点数周りのバグを探してみました。

そうして調べていく中で、浮動小数点数の四捨五入について何個かエッジケースがあることに気づきました。また、各種プログラミング言語の中の人が必ずしも浮動小数点数に詳しくないこともわかってきました*1。まずはround関数のエッジケースと各言語の対応状況について紹介します。



