今週は国際浮動小数点数ウイークですので、週の最後もやはり浮動小数点数ネタです。
Rubyのround関数の実装に関して、1.8.6 patchlevel 114と1.8.6 patchlevel 230の間に変更が入っています。1.8.6-p230のリリース時期は2008/06/20のようですから、1.8.7(2008/06/01リリース)から変更されたと言っていいかもしれません。
これらは、僅かながら挙動が違っています。MacOSX環境で実験しました。(再現できるのはFreeBSDとMacOSXだけのような気がします)
$ /usr/bin/ruby --version ruby 1.8.6 (2008-03-03 patchlevel 114) [universal-darwin9.0] $ /usr/bin/ruby -e 'p 9007199254740991.0.round;' 9007199254740992 $ /opt/local/bin/ruby --version ruby 1.8.7 (2008-08-11 patchlevel 72) [i686-darwin9] $ /opt/local/bin/ruby -e 'p 9007199254740991.0.round;' 9007199254740991
なんと、同じ数字の丸め結果が違う数字になりました。中身を簡単に説明すると、前者は自前実装していたのが、後者はlibmのroundに丸投げしています。roundが無い環境のために自前のroundも用意してありますが、これも1.8.6-p114以前とは異なる実装です。
1.8.6-p114の方が不思議な挙動に見えますので、修正自体は良いと思います。とはいえ、PHP以外の言語でも、マイナーバージョンアップで基本的な関数の実装をいじることがあるんですね。その点は少しビックリしました。
続きを読む