2

私はそのようなクラスを持っています:

public class Test
{
    public void CheckValue(float val)
    {
        if (val == 0f)
        {
            //Do something
        }
    }
}

//Somewhere else..
void SomeMethod
{
    Test t = new Test();
    t.CheckValue(0f);
}

if (val == 0f)チェックが返されることは保証されていtrueますか? それとも、浮動小数点数で演算を実行したときに精度が失われるだけですか?

4

3 に答える 3

4

精度を失うことはありません。一部の浮動小数点値を 10 進数で記述すると、不正確になります。それらに対して操作を行うと、これらの不正確さが加算されたり、相殺されたりする可能性があります。

あなたの場合、010進数と2進浮動小数点の両方で完全に正確に記述できるので、うまくいくはずです。他の値はそうではない可能性があり、(他の人が指摘しているように)==浮動小数点値に依存しないでください。

詳細については、http: //floating-point-gui.de/を参照してください。

于 2013-03-05T10:23:00.243 に答える
1

つまり、.を保持する 32 ビット相当のメモリでは、すべての浮動小数点数 (すべての無限分散) を完全に表すことはできないということですfloat。完全に表現できない数値のエラー値はごくわずかですが、存在します。

たとえば、1/3 は、最も近い float 表現で (おおよそ) 0.333333343267 です。10 進数で 7 桁の精度が得られると、少し問題が発生します。1 を 3 で割り、後で 3 を掛けたとします。結果は 1 ではなく、1.0000000298 となり、変化します。だから(1/3)*3 =/= 1

これらの表現上のエラーが、浮動小数点値を直接比較することが不適切な方法と見なされる理由です。

これらの小さなエラーの影響を最小限に抑える必要がある状況では、エラーが蓄積しないようにできる限りのことを行う必要があります。たとえば、一連の座標を少しずつ回転させると、不完全な結果が得られます。これは、各回転操作 (完全な float 表現を持つ可能性が低いsinと のcos値を使用) によって発生するエラーが時間の経過とともに蓄積されるためです。全体の角度変化を追跡し、元のベクトルを毎回回転させて、エラー値を小さくすることをお勧めします。

これがあなたを噛む可能性のある別の場所は、forループです。1ステップあたり1/30000で10,000ステップを実行したい場合は、ループ変数にintを使用し、現在位置を除算として計算します。はい、遅くなりますが、はるかに正確です。浮動小数点数を使用すると、毎回除算すると 7 桁を超えるのではなく、信頼できる 10 進数の有効桁数が約 3 桁になるまでエラーが蓄積されます。

速度は素晴らしいですが、状況によっては精度が優れています。

はい、ばかげているように見えますが、これらのエラーは実際に増加する可能性があります. それほど重要でない場所もあれば、エラー ファクトリが蔓延している場所もあります。

于 2013-03-05T11:36:46.517 に答える
-2

浮動小数点数を「==」と比較してはいけません。代わりに、境界線を使用できます。たとえば、 == 0 を比較する代わりに、次のようなことができます

float border = 0.00000001;
if( (val - border) <= 0 && (val + border) >= 0)
于 2013-03-05T10:23:58.573 に答える