4

モーション コントロールに使用するコードを開発していますが、pow 関数に問題があります。VS2010 を IDE として使用しています。

これが私の問題です:私は持っています:

    double p = 100.0000;
    double d = 1000.0000;
    t1 = pow((p/(8.0000*d),1.00/4.000);

この最後の関数を評価すると、結果としてより良い近似が得られません。私は 7 桁の 10 進数を正しく取得していますが、その結果の桁はすべてゴミです。pow 関数は、入力変数のみを float としてキャストし、計算を続行すると推測しています。

  1. 私は正しいですか?
  2. もしそうなら、より良い精度のために pow を再実装するために「インスピレーション」を得ることができるコードはありますか?

編集:解決しました。

結局、OGRE 3D フレームワークで使用されていた Direct3D が原因で、FPU 構成ビットに問題がありました。

OGRE を使用している場合は、構成 GUI で「Floating-point mode=Consistent」を設定します。

生の Direct3D を使用している場合は、CreateDevice を呼び出すときに、必ず「D3DCREATE_FPU_PRESERVE」フラグを渡してください。

元の投稿:

FPU のデフォルトの精度を単精度に変更するライブラリを使用している可能性があります。次に、すべての浮動小数点演算は、double であっても、実際には単精度演算として実行されます。

テストとして、_controlfp( _CW_DEFAULT, 0xfffff ); を呼び出してみてください。( を含める必要があります) 計算を実行して、正しい結果が得られるかどうかを確認してください。これにより、浮動小数点制御ワードがデフォルト値にリセットされます。他の設定もリセットされるため、問題が発生する可能性があることに注意してください。

浮動小数点の精度を変更する一般的なライブラリの 1 つは Direct3D 9 (おそらく他のバージョンも) です。デフォルトでは、デバイスの作成時に FPU を単精度に変更します。これを使用する場合は、デバイスの作成時にフラグ D3DCREATE_FPU_PRESERVE を指定して、FPU の精度が変更されないようにします。

4

2 に答える 2

4

FPU のデフォルトの精度を単精度に変更するライブラリを使用している可能性があります。次に、すべての浮動小数点演算は、doubles であっても、実際には単精度演算として実行されます。

_controlfp( _CW_DEFAULT, 0xfffff ); テストとして、計算を実行する前に ( を含める必要がある) を呼び出し<float.h>て、正しい結果が得られるかどうかを確認できます。これにより、浮動小数点制御ワードがデフォルト値にリセットされます。他の設定もリセットされるため、問題が発生する可能性があることに注意してください。

浮動小数点の精度を変更する一般的なライブラリの 1 つは Direct3D 9 (おそらく他のバージョンも) です。デフォルトでは、デバイスの作成時に FPU を単精度に変更します。使用する場合は、デバイス作成時にフラグを指定してD3DCREATE_FPU_PRESERVE、FPU の精度が変更されないようにしてください。

于 2012-07-17T15:45:13.373 に答える
0

精度が 7 桁しかないことをどのように判断しましたか? t1正しい出力形式を指定して印刷していますか? 私のマシンでは、VS2010 を使用して、次のコードを実行します。

int main()
{
    double p = 100.0000;
    double d = 1000.0000;
    double t1 = pow(p/(8.0000*d),1.00/4.000);

    printf("t1=%.15f\n", t1); // C
    std::cout << "t1=" << std::setprecision(15) << t1 << '\n'; // C++
}

次の出力が生成されます。

t1=0.334370152488211
t1=0.334370152488211
于 2012-07-17T15:31:02.980 に答える