roundとprintfの丸めに関する不整合
さて、先日の記事「PHP5.3.0alpha3のround関数の実装がPHP5.2.6と変わった」でも紹介したPHPのround関数を改善する提案には、printfとの整合性についても書かれています。というのも、printfで"%.2f"などと精度を指定した場合、round関数と同様に丸めが発生するからです。
提案文書によれば提案者は「以前はprintfもroundに合わせるべきだと思っていたが、やはりprintfは他の言語でもよく使われているから変更すべきではない。ドキュメントに違いが書いてあれば十分だ。」という結論に至ったようで、PHP5.3.0のprintfは変更されていません。
不整合が存在しても実際に困ることは無いのでしょうが、「不整合があるよ」と聞くのは気分の良いものではありません。さすがPHPだなあ、という気分になりましたが、他の言語でどうなっているのか気になったので、念のためPythonでも実験してみました。例によってMacOSX環境です。
$ python -c 'x=0.235; print "%.2f\n%f" % (x, round(x,2))' 0.23 0.240000 $ python -c 'x=0.236; print "%.2f\n%f" % (x, round(x,2))' 0.24 0.240000
0.235をprintfモドキ(Pythonのこれは何と言うんでしょう?)とround関数とを使って小数点以下第2位までに丸めてみたところ、違う結果になりました。なんだ、Pythonも整合性とれてないんだ。
さすがPHPとか言ってごめんなさい。
補足しておくと、Linux環境のPythonでは不整合を見つけられませんでした。それはそれで不思議な気がします。でも不整合が見つかりました。ソースを読まずに想像で書きますが、内部的にシステムのsprintfを呼んでいる気がします。つまり、最初から整合性を取る気がゼロなんでしょう。
$ python -c 'x=0.125; print "%.2f\n%f" % (x, round(x,2))' 0.12 0.130000
そもそもCのprintfでの丸め方式自体が未定義なんですね。それなら不整合があってもいいや。