2

XとYのすべての組み合わせを反復処理しようとしています。値を0.01ずつインクリメントしています。これは2倍ですが、実際には0に達することはありません。

for (double x = -50; x < 50; x += 0.01)
{
     for (double y = -50; y <50; y += 0.01)
     {
          //Some code
     }
}

なぜこれが起こるのか考えていますか?私はそれが「ダブル」と関係があると思います、もしそうなら、私は代わりに何を使うことができますか?

更新:10進数に変更し、すべての10進数を変更して末尾に「m」を付けました。今はすべてうまくいきます、私はあなたたちを愛しています:D

コードは次のようになります-

for (decimal x = -50; x < 50; x += 0.01m)
{
      for (decimal y = -50; y < 50; y += 0.01m)
      {
            // Some code
      }
}
4

7 に答える 7

2

次のようなゼロをテストしていると思われます。

if (x == 0.0) {
    // it is zero.
}

これは、浮動小数点の丸め誤差が原因で失敗する可能性があります。

浮動小数点数の特性の 1 つは、多くの 10 進数を正確に表現できないことです。この場合、0.01 の最も近い表現はわずかに「オフ」であることがわかります。したがって、5,000 倍に加算0.01すると、結果は正確には になりません。-50.00.0

xゼロプラス/マイナスの小さなエラーかどうかをテストする必要があります。たとえば0.00001、この場合は問題ありません。

さらに良いのは、ループ変数を整数として宣言し、それを 0.01 で割ってxと のy値を与えることで、丸めの問題全体を回避できることです。例えば

for (int i = -5000; i < 5000; i++) {
    double x = i / 0.01d;
    // etcetera

実際、あなたのコードは0.01ではなくを使用し0.01dているため、表現のエラーは本来あるべき以上のものになると思います...

于 2013-02-02T14:28:42.303 に答える
2

丸め/切り捨てエラーのため、値 0.01 を double に正確に格納することはできません。そのため、それらのいくつかを一緒に追加すると、エラーの大きさが増加し、0 を逃す可能性があります。代わりに、10 進数型を試すか、int を反復処理します。

于 2013-02-02T14:31:28.437 に答える
2

問題は、コンピューターの浮動小数点数は通常、10 進数値を正確に表すことができず、概算値に過ぎないことです。詳細については、浮動小数点数に関する wiki 記事を確認してください。

次のようなものを使用すると、コードがうまく機能します。

for (int idxX = -5000; idxX < 5000; idxX += 1)
{
    double x = (double) idxX / 100.0;

    for (int idxY = -5000; idxY < 5000; idxY += 1)
    {
        double y = (double) idxY / 100.0;

        //Some code
    }
}

これにより、浮動小数点数の問題の一部が回避されます。

于 2013-02-02T14:32:06.037 に答える
0

このトリックを試してください:

for (int x = -5000; x < 5000; x++)
    {
         for (int y = -5000; y <5000; y++)
         {
              System.out.println((double)x/100.0+" ~~ "+(double)y/100.0);
         }
    }

よろしく、

于 2013-02-02T14:32:34.067 に答える
0

代わりに 10 進数を使用してください。次に、0にヒットします。doubleで計算すると、丸め誤差が発生します

于 2013-02-02T14:32:36.600 に答える
0

ほとんどの C 派生言語では、doublefloatは基数 2 の累乗の数値です。これは、10 進数自体とはほとんど関係がなく、常に正確に格納できるとは限らず、近似値を格納するだけであることを意味します。

これに対する解決策は、基数 10 のべき乗を使用することです。幸いなことに、C# には次のプロパティを持つ型がありますdecimal。に置き換えるdoubledecimal、おそらく準備完了です。

于 2013-02-02T14:39:28.120 に答える
0

これはどう:

if (x == (.01-.01)){}
于 2013-02-02T14:40:06.253 に答える