1

アプリケーションに奇妙なバグがあり、この単純なテスト ケースに絞り込むことができました。

protected void Page_Load(object sender, EventArgs e)
{
    bool isHeightExceeded = IsHeightExceeded(10.16f, 127.15f);
    lit.Text = isHeightExceeded.ToString();
}

private bool IsHeightExceeded(float y, float height)
{
    float nextHeight = y + height;
    return (137.31f - nextHeight) < 0;
}

これをデバッグ モードでビルドして実行すると、isHeightExceeded bool は (予想どおり) False になりますが、リリース モードでビルドして実行すると、True になります。

これを引き起こす舞台裏で何が起こっているのでしょうか? 浮動小数点の精度と関係があると推測していますが、正確にはわかりません。

どんな助けでも大歓迎です。

4

2 に答える 2

4

10.16f + 127.15fの値は64(または80)ビットで計算されてから137.31fと比較されると思います...一方、リリースモードでは、値が計算されてから32ビットに切り捨てられてから比較されます。基本的に、中間値がより低い精度にクランプされていない場合、次のような結果を得ることができます。

それが問題である場合、それはおそらくfloatあなたが使用したり、最初から始めるべきではないことを示唆していますdouble-これらが正確な値であることが意図されている場合は、decimal代わりに使用してください。

于 2012-08-07T10:31:05.063 に答える
1

10.16 + 127.15 は正確に 137.31 に等しく、これは の理論値(137.31f - nextHeight)が 0 であることを意味します。

数値演算が関係しているため、数値精度の問題が発生する可能性があります。デバッガを使用する場合と使用しない場合では、この問題の扱いが異なる可能性があります。これは単なる推測ですが、私は驚かないでしょう。

いずれの場合も、精度エラーを考慮してコードを修正し、許容範囲のカスタムイプシロン値 (0.00001 など) を使用して、人間の読者やユーザーにとって予測可能な結果を​​得る必要があります。この許容誤差を追加しないと、コードは double 値に対してのみ正しく機能し、人間がコードを読み取る場合には正しく機能しない可能性があります。

于 2012-08-07T10:31:51.900 に答える