Top Page [◀◀]  2   3   4   5   6   7   8   9   ... [▶▶Last Page

浮動小数点誤差について

お世話になっております。

みゅうと申します。

 

SH7211上で動作していたプログラムを、SH7216上へと移植しているのですが、

演算の結果が同一にならず困っております。

 

厳密には8.333332500となるようなfloat値、8.333332①に対して×1000000②をすると

両CPU上で、共に8333333となります。(切り上げor制約?)

これに対して、元に戻す演算である、÷1000000をすると③

7211上では、8.333332になり(まるめ指定省略=round-nearest?)、

7216上では、8.333331になります(round-nearest指定)。

該当部のソースコードは以下です。

    p->acc_par_spd_par_2 = (float) p->accele / speed / 2;
    p_par2 = p->acc_par_spd_par_2;                 //① ※左辺右辺共にfloat型です
    p->acc_par_spd_par_2 *= (float) 1000000;  //②
    par2 = p->acc_par_spd_par_2 / 1000000;    //③ ※同上

また、SH7216において上記コード部によって算出した①③がそろっているように見えても、

実際には内部表現が異なる場合があります。

floatでは有効桁を超えた情報は欠落すると思っているのですが、

大小比較において真となります。

 

これらについて、詳細をご教授いただければと思います。よろしくお願いします。

  • > floatでは有効桁を超えた情報は欠落すると思っているのですが、

    同じプロセッサでも丸めモードの違いで結果は違ったりしますよ。
  • > SH7211上で動作していたプログラムを、SH7216上へと移植しているのですが、
    > 演算の結果が同一にならず困っております。

    SH7211はFPUが搭載されていない仕様に対して
    SH7216は搭載されてる仕様みたいなので、SH7216でもFPUを使わずにソフトfloatで演算する設定にしたら同じ結果になるかもしんないですね。
  • > 厳密には8.333332500となるようなfloat値、8.333332①に対して

    IEEE 754 の binary32 で表現できる 8.333332 に近い値は

    8.33333110809326171875 か
    8.333332061767578125 か
    8.33333301544189453125 のいずれかなので、「厳密には8.333332500となるようなfloat値」は前提としておかしいと思います。
  • In reply to fujita nozomu:

    返信ありがとうございます。
    この厳密値の話は、実際の計算値のお話です。

    おっしゃる通り7216はFPUでの計算、7211ではCPUでの計算になるのだと思います。
    7216においてFPUを使わないという設定はないので、
    もし7216において全く同じ計算をさせたければ、
    アセンブラで記述するしかないということでしょうか?
    (アセンブラはわかりませんが……)
  • In reply to みゅう:

    SH7216 の FPU なし版が SH7214 であり、開発ツールのマイコンの設定をそれにすれば SH7216 で FPU を使用しない動作は可能かもしれません。細かい仕様の差異がないかはよく確認する必要があります。
    他、浮動小数点演算の演算誤差に影響するコンパイラオプションは存在するので SH7211 のプログラムを作成した際の設定は SH7216 でも同様にする必要があります。コンパイラの版についても同様です。

  • そもそもの話として

    > 演算の結果が同一にならず困っております。

    浮動小数点演算の結果がびったり一致しなかったとして何に困るんだかサッパリわからん。
    一致する前提で考えればすべての演算結果がそうなることを保証する必要が出てくると思うがそんなことが可能なんだろうか?
  • >SH7211上で動作していたプログラムを、SH7216上へと移植しているのですが、
    >演算の結果が同一にならず困っております。
    これの回答は
    >SH7211はFPUが搭載されていない仕様に対して
    >SH7216は搭載されてる仕様みたい
    ということで、どうでしょう。
  • In reply to IKUZO:

    返信ありがとうございます。こちらの返信が遅れましてすみません。

    SH7214として設定するという点や、コンパイラの他の設定、コンパイラ自体のバージョンについて、
    確認してみます。
    また、演算結果についてですが、移植したプログラムがうまく動作せず、
    可能性として、この浮動小数点値を用いてさらに計算をした値が、
    移植前後で異なっている事が原因か?という状況です。
    レベルの異なる周期割り込みが4種あり、動作不良の原因の特定が困難なので、
    可能性の一つとして値が異なるのを解消しておきたい、という状況です。
  • In reply to みゅう:

    みゅうさん
    FPUを使用する、しないとか、設定もいろいろあると思いますよ
    型番自体が完全互換でない限りは動作が異なっていて当然のような気がします
    IOとかBUS周りINT関連とか基本的なところから、潰していくしかないですね。
  • In reply to みゅう:

    > また、演算結果についてですが、移植したプログラムがうまく動作せず、
    > 可能性として、この浮動小数点値を用いてさらに計算をした値が、
    > 移植前後で異なっている事が原因か?という状況です。

    うまく動作しないという現象が再現性含めて確認できるのならそこから原因を突き止めるべきであり、なんかわからんけど違うところから同じにしていくかという方法は問題の原因との因果関係も不明なまゝ現象が現れなくなってしまう可能性もあり良い方法ではありません。
  • In reply to fujita nozomu:

    >演算結果についてですが、移植したプログラムがうまく動作せず、
    >可能性として、この浮動小数点値を用いてさらに計算をした値が、
    >移植前後で異なっている事が原因か?という状況です。
    >レベルの異なる周期割り込みが4種あり、動作不良の原因の特定が困難なので、
    >可能性の一つとして値が異なるのを解消しておきたい
    可能性の一つとして値が異なるということでしたので
    他にも問題個所があるのではと。まあ今わかっている問題解決を進めていくのは大切ですね。わたくし等は数万行あるようなソースの手あたり次第に調べていくのではなく、機能ごとに正常に動作しているのかどうか調べていきます、当然問題ない箇所も重複して確認することにはなりますが。

  • In reply to IKUZO:

    返信ありがとうございます。

    なんかわからんということではなく
    全く同じパラメータ・同じロジックでありながら演算結果が違うので、
    ほぼこれ、という段階でのことです。確定してはいないので可能性と表現しました。
    他に思いつく要因もありませんが、確定させるような検証をするには
    1から書きなおすのと同じくらいの時間が見込まれるので、
    ほぼこれ、というところから、アタリを付ける手を取っています。
    よろしくないことは承知しています。

    で、さしあたりなのですが、
    SH7214として設定してビルド、動作させたところ、値も一致し動作不良がなくなりました。
    SH7214はSH7216のFPUなし版、ということで、
    浮動小数点演算がFPUで(より正確に)行われることが原因ということだと思います。
    こうなると、関係する演算を見直すというか、
    演算に関して、書き直しだと思います……
  • In reply to みゅう:

    > SH7214はSH7216のFPUなし版、ということで、
    > 浮動小数点演算がFPUで(より正確に)行われることが原因ということだと思います。

    ↓を見る限りではソフト float の SH7211 より FPU を搭載した SH7216 の方が誤差が大きく演算精度は悪そうです。

    > 両CPU上で、共に8333333となります。(切り上げor制約?)
    > これに対して、元に戻す演算である、÷1000000をすると③
    > 7211上では、8.333332になり(まるめ指定省略=round-nearest?)、
    > 7216上では、8.333331になります(round-nearest指定)。

    他、FPU からソフト float に変更することで動作不良が表れなくなったとして、演算精度の違い以外にも
    ・コードサイズの違いにより配置が異なり不具合が露見したりしなかったり
    ・演算速度の違いによりタイミングによる不具合が露見したりしなかったり
    ・NaN やゼロ除算等での振る舞いの違いにより不具合が露見したりしなかったり
    ・コンパイラやライブラリの不具合

    様々な可能性は考えられると思うので自分なら原因を決めつけるようなことはしませんね。

Top Page [◀◀]  2   3   4   5   6   7   8   9   ... [▶▶Last Page