浮動小数点誤差について

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

みゅうと申します。

 

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では有効桁を超えた情報は欠落すると思っているのですが、

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

 

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

Parents
  • > 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 やゼロ除算等での振る舞いの違いにより不具合が露見したりしなかったり
    ・コンパイラやライブラリの不具合

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

Reply
  • > 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 やゼロ除算等での振る舞いの違いにより不具合が露見したりしなかったり
    ・コンパイラやライブラリの不具合

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

Children
No Data