1

私はループのためにこれを持っています:

for (double x = -1 * (display.Width / zoom); x <= (display.Width / zoom); x += 0.1)
{
    //..
}

xは -20 に初期化され、20 と比較されます。理想的には、x-20、-19.9、-19.8 などのようにインクリメントされます。実際には、これは起こりません。一部の反復では、実際には小数点の後に 1 桁しかありませんが、他の反復では、たとえば -19.8999999 のように正確ではありません。これは、私のプログラムのいくつかの非常に苛立たしい (そして見つけるのが難しい) バグの原因です。

x「比較的丸い」ままになるようにするにはどうすればよいですか?

4

7 に答える 7

4

使用しないdoublefloat、この種の精度が必要な場合はdecimal代わりに使用してください。

これは、特定の分数を 2 進数で正確に表現できないために発生しています。What Every Computer Scientist Should Know About Floating-Point Arithmeticを読むことをお勧めします。

于 2013-01-04T21:22:15.070 に答える
2

これは、 a のdouble格納方法に関係しています。decimal代わりにa を試してください。

于 2013-01-04T21:22:38.203 に答える
2

-200 に初期化され、200 と比較される整数ループ カウンターを使用xし、各反復で実数を計算します。

UPD: Decimal を使用する方がおそらく優れています。

于 2013-01-04T21:23:20.637 に答える
1

私があなたを正しく理解しているなら...なぜあなたはそれを丸めるのですか?

Math.Round(x,1)
于 2013-01-04T21:26:12.613 に答える
0

double を使用する必要がある場合は、次のように使用できます。

double x = 0.0;
while (x <= 3.0)
{
   //Do your stuff
   x = Math.Round(x + 0.1, 1);
}
于 2017-01-01T11:08:35.780 に答える
0

浮動小数点数 (Double/Float) は正確ではありません。代わりに -200 と 200 を int として使用してください。これにより、浮動小数点精度の不足を心配する必要がなくなります。

この不正確さの詳細については、このドキュメントをお勧めします。 http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

于 2013-01-04T21:25:21.963 に答える
0

可能な限り正確にしたい場合は、スケールアップして、intまたはlong...たとえば:

long _Z = (long) ((display.Width * 10) / zoom);

for (long _x = -1 * _Z; _x <= _Z; _x += 1)
{
    double x = ((double)_x) / 10.0;
    // ...

}
于 2013-01-04T21:25:59.677 に答える