6

double を基本単位として使用する構造体に基づく C# 3.0 の小さな 3D ベクトル クラスがあります。

例: 1 つのベクトルの y 値は

-20.0 straight

の y 値を持つベクトルを減算します。

10.094999999999965

私が期待する y の値は

-30.094999999999963         (1)

代わりに私は得る

-30.094999313354492         (2)

計算全体を 1 つのスレッドで実行すると、(1) が得られます。また、デバッガーと VS クイック ウォッチは (1) を返します。しかし、あるスレッドでいくつかの反復を実行し、別のスレッドから関数を呼び出すと、結果は (2) になります。これで、デバッガーも (2) を返します!

.NET JIT が値をメモリ (Web サイト Jon Skeet) に書き戻す可能性があることに留意する必要があります。これにより、精度が 80 ビット (FPU) から 64 ビット (double) に低下します。ただし、(2) の精度はそれをはるかに下回ります。

ベクトルクラスは基本的に次のようになります

public struct Vector3d
{
  private readonly double _x, _y, _z;
  ...
  public static Vector3d operator -(Vector3d v1, Vector3d v2)
  {
      return new Vector3d(v1._x - v2._x, v1._y - v2._y, v1._z - v2._z);
  }  
}

計算はこれくらい簡単

Vector3d pos41 = pos4 - pos1;
4

1 に答える 1

5

はい、結果はスレッドに依存する可能性があると思います。

私の推測では、コードのある時点でDirectXを使用しています。これにより、FPUの精度が設定され、スレッドごとに設定されると思います。

これを修正するには、を呼び出すときにD3DCREATE_FPU_PRESERVECreateDeviceフラグを使用します。これはパフォーマンスに影響を与える可能性があることに注意してください。管理された同等物はCreateFlags.FpuPreserveです。

この関連する質問を参照してください。少なくとも表面上は少し異なって見えるため、これを複製として閉じることはお勧めしません。両方を使用すると、答えを見つけやすくなります。)

于 2010-05-17T09:40:23.123 に答える