ruby-trunk-changes r33282 - r33286

えー本日は浮動小数点数演算の誤差と x87 FPU の問題についての解説です。結果として今日は変更なし(version.h の日付更新のみ)です。

marcandre:r33282 2011-09-16 02:13:51 +0900

Range の範囲とstepが Float だった時に浮動小数点数の誤差により直感的な期待と異なる結果になるものについて、計算の途中で変数に格納するようにしたら直ったから入れて、と投稿されたパッチを適用したものです。 [ruby-core:39198] [Bug #4576]
でもこの修正にはあまり意味がないので次で revert されています。詳しい理由はそちらで。

svn:r33283 2011-09-16 02:13:56 +0900

version.h の日付更新。

naruse:r33284 2011-09-16 10:12:46 +0900

r33282 を revert しています。
チケットみると自分が i686 でのテストの失敗を報告してた件ですね。それをみて思い出いましたが、この問題は x86 系の古い CPU だと浮動小数点数演算を x87 FPU (Intel 8087 とその子孫達)というコプロセッサで行なっていて、この FPU では浮動小数点数レジスタが 80bit あってメモリ上での 64bit の表現と異なるために誤差の違いが生じるということによるものです。 gcc では -ffloat-store というオプションを付けると、必ず演算するたびに一旦メモリに値を戻して 64bit 表現に変換するようにするので回避できるはずなのですが、r33282 はこれを変数に格納することでやろうとしているらしく、そのような対処は当然コンパイラの最適化によって無視される可能性があるのであんまり意味がありません。FPU の 80bit のレジスタ上で演算が繰り返されてしまうと演算結果に差が生じるためです。チケットの報告をみるとたまたまうまくいった時があったみたいですが、最適化オプションをつけるとだめみたいです。またチケットには naruse さんと usa さんのコメントで FPU の問題の解説とか、-ffloat-store のかわりに -msse2 でもいい(ただし当然 SSE2 が利用できる CPU でないとだめ)とか、VC の場合は -Op や -fp:precise といったオプションがあるというような説明もあるので気になる方はそちらも見てみてください。

marcandre:r33285 2011-09-16 15:44:59 +0900

でもういっかい同じ修正をコミットしています。

naruse:r33286 2011-09-16 16:09:24 +0900

でもう一度 revert しています。