私は書いているCコードのチャンクを最適化しようとしていますが、製品は分割よりも速いことに気付いています。これはよく知られている問題で、どこでもきれいに説明されています。逆算の精度と精度
この最適化を念頭に置いて、私は同じ数字を何度も何度も繰り返しているので、その数字の逆数を1回計算してから乗算しようとしました。しかし、私は結果がまったく同じではないことに気づいた。
I'vaは私が話しているの違いが明確である、本当に単純な例を記述するために管理:、あなたが見ることができるように、私はどこDinv = 1/D
、a/D
はa*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/D
がa*Dinv
に等しくないことが、b/D
がまったく同じであることがわかりますb*Dinv
となります。この動作はテストされた数値で変化します(a
とb
は私が本当に興味を持っている数字ではありません。私の質問は:
- なぜ
a/D
とa*Dinv
が異なるのですか? - なぜいくつかの数値はテストに合格するのですか?
- 正確性について何か言えますか?私は、
a/D
とa*Dinv
を与えられて、私たちはそれらのいずれかが他よりも正確であると言うことができますか?
ありがとうございました!
手順を見てください。 'a/D'が最も正確になります。 'Dinv = 1/D'は' a * Dinv'が起こる前に切り捨て/丸めを行います。 – matt