x86_64だと浮動小数点演算の精度が低下する

12月 9th, 2008 by tune Leave a reply »

64bit OSで動かすと32bitの時と処理結果が異なるプログラムで悩んだメモです。

調べていくとfloatを使った浮動小数点演算で誤差が出ることがわかりました。分からなかったのが、IEEE754でfloatの演算精度は32bitと規定されているのになぜ同じソースから作ったプログラムで結果が違うのかということです。

x86では浮動小数点演算にx87を使うのですが、この演算精度は32bitや64bitではなく、80bitで行われるそうです。この辺の話は 浮動小数点演算ではまった話 – bkブログとかBK通信に詳しく載ってます。要約すると32bitの精度で誤差が生じる計算が含まれていても”たまたま”うまく計算できることがある ということです。

たまたま精度よく計算できるプログラムをx86_64に持っていってコンパイルしようとします。このとき、x86_64では必ずSSEが使えるため、コンパイラはデフォルトでSSEを使うようにコンパイルします。SSEで浮動小数点演算を行うと演算精度がx87の80bitよりも悪くなるため、本来生じるはずだった演算誤差が表面化することになります。

高林さんがBK通信で書いているMac OSで演算結果が違うというのも、Mac OSが64bitOSであることが関係している気がします。

バイナリーハックス買おうかな。

Binary Hacks ―ハッカー秘伝のテクニック100選
高林 哲 鵜飼 文敏 佐藤 祐介 浜地 慎一郎 首藤 一幸
オライリー・ジャパン
売り上げランキング: 23306
おすすめ度の平均: 5.0

5 ハードコア?なソフトウエア
5 大工さんにおける電動工具の紹介本
5 当然教科書ではない。でも、とても参考になります。
5 バイナリアンの基本

Advertisement

2 comments

  1. zxa より:

    そもそも、0.1ですら正しく表現できない浮動小数点演算で、計算精度を求めるのが間違っている気が…
    ひょっとして
    a == b
    なんていう演算やっていないでしょうね??
    abs(a-b)<1.0E-6
    ですよ。

    バイナリハックス、あまりにもマニアックすぎて不要なので、あげましょうか…
    mainの前に関数を呼び出せても、最近5年ぶりにまともにJavaで開発している身としては関係なし。

  2. admin より:

    > a == b
    さすがにこんな計算してないですよ。
    まぁ、計算精度の違いに気づいたのは大きい数値と小さい数値の加減算という基本的な箇所ですが…

    バイナリハックスいらないならください