2016-08-25 25 views
1

私は書いているCコードのチャンクを最適化しようとしていますが、製品は分割よりも速いことに気付いています。これはよく知られている問題で、どこでもきれいに説明されています。逆算の精度と精度

この最適化を念頭に置いて、私は同じ数字を何度も何度も繰り返しているので、その数字の逆数を1回計算してから乗算しようとしました。しかし、私は結果がまったく同じではないことに気づいた。

I'vaは私が話しているの違いが明確である、本当に単純な例を記述するために管理:、あなたが見ることができるように、私はどこDinv = 1/Da/Da*Dinvに等しいかどうかをテスト

#include <stdio.h> 

int main(){ 
    double D = 1.1891; 
    double Dinv = 1./D; 

    double a = 23123.1234; 
    double b = 156.123871; 

    printf("1/D = %.60f\n", 1./D); 
    printf("Dinv = %.60f\n", Dinv); 
    printf("1/D == Dinv? %s\n\n", 1./D == Dinv ? "True" : "False"); 

    printf("a/D = %.60f\n", a/D); 
    printf("a*Dinv = %.60f\n\n", a*Dinv); 
    printf("a/D == a*Dinv? %s\n\n", a/D == a*Dinv ? "True" : "False"); 

    printf("b/D = %.60f\n", b/D); 
    printf("b*Dinv = %.60f\n\n", b*Dinv); 
    printf("b/D == b*Dinv? %s\n\n", b/D == b*Dinv ? "True" : "False"); 
} 

bと同じテストです。私のマシンでこのコードの出力は以下の通りです:

1/D = 0.840972163821377516335076052200747653841972351074218750000000 
Dinv = 0.840972163821377516335076052200747653841972351074218750000000 
1/D == Dinv? True 

a/D = 19445.903120006725657731294631958007812500000000000000000000000000 
a*Dinv = 19445.903120006729295710101723670959472656250000000000000000000000 

a/D == a*Dinv? False 

b/D = 131.295829619039608360253623686730861663818359375000000000000000 
b*Dinv = 131.295829619039608360253623686730861663818359375000000000000000 
b/D == b*Dinv? True 

あなたが出力で見ることができるように、テスト結果が異なっている:我々はa/Da*Dinvに等しくないことが、b/Dがまったく同じであることがわかりますb*Dinvとなります。この動作はテストされた数値で変化します(abは私が本当に興味を持っている数字ではありません。私の質問は:

  1. なぜa/Da*Dinvが異なるのですか?
  2. なぜいくつかの数値はテストに合格するのですか?
  3. 正確性について何か言えますか?私は、a/Da*Dinvを与えられて、私たちはそれらのいずれかが他よりも正確であると言うことができますか?

ありがとうございました!

+0

手順を見てください。 'a/D'が最も正確になります。 'Dinv = 1/D'は' a * Dinv'が起こる前に切り捨て/丸めを行います。 – matt

答えて

1

a*(1.0f/D)である、a/Da*Dinvの結果が原因a*Dinvでも異なっていてもよく、部分的に質問に答えるために、一つの追加の操作は、潜在的に精度の損失を引き起こす、複雑です。