0

このコードの理由を理解したいと思います。

double r,d,rc;
scanf("%lf %lf", &r, &d);
rc = (r * r) - (d/2) * (d/2);
printf("%.2f\n", M_PI * rc);

これよりも正確な結果を返します(rc変数の割り当てなし):

double r,d,rc;
scanf("%lf %lf", &r, &d);
printf("%.2f\n", M_PI * (r * r) - (d/2) * (d/2));

別の関連する質問:なぜn * nより良いのですpow(n,2)か?

4

2 に答える 2

5

最初のコードサンプルは以下を計算します:

M_PI * ((r * r) - (d/2) * (d/2));

2番目の計算:

(M_PI * (r * r)) - (d/2) * (d/2);

の呼び出しは、ほとんどのコンパイラでpow(n, 2)、と同じです。まったく同じアセンブリが放出されますn * n。これは、「強度低減」と呼ばれる最適化によるものです。ほとんどの実装では、指数が2であるかどうかを確認し、その場合を1回の乗算に減らします。最適化されていないバージョンは、関数呼び出しといくつかの分岐が必要なため、少し高価です。pow()

M_PIこれはC標準の一部ではないため、まったく同じコードにコンパイルされる同等のものを使用できることに注意してください。

double M_PI = 4.0 * atan(1.0);
于 2013-03-14T22:59:44.617 に答える
0

2番目の質問に答えるには; powは任意の累乗を実行するように設計されていますが、累乗が一定の場合に答えを計算するより高速な方法があることは驚くべきことではありません。単一の乗算は高速です(単一のプロセッサ命令のみ)が、への呼び出しにpowは関数呼び出しのオーバーヘッド(今のところ最適化を無視)と、答えが得られるまで繰り返し乗算する反復アルゴリズムが必要です。そのようなことを避けるための数学的ショートカットを見ることができるとき、あなたはそれを使います。

于 2013-03-14T23:01:55.977 に答える