问题
I would like to understand why this code:
double r,d,rc;
scanf("%lf %lf", &r, &d);
rc = (r * r) - (d/2) * (d/2);
printf("%.2f\n", M_PI * rc);
returns more precise result than this one (without rc
variable assignment):
double r,d,rc;
scanf("%lf %lf", &r, &d);
printf("%.2f\n", M_PI * (r * r) - (d/2) * (d/2));
Another, related, question: why is n * n
better than pow(n,2)
?
回答1:
The first code sample computes:
M_PI * ((r * r) - (d/2) * (d/2));
The second computes:
(M_PI * (r * r)) - (d/2) * (d/2);
A call to pow(n, 2)
is the same as n * n
, on most compilers. The exact same assembly will be emitted. This is due to an optimization called "strength reduction" -- most pow()
implementations will check to see if the exponent is 2, and reduce that case to a single multiplication. The unoptimized version is slightly more expensive since it requires a function call and some branching.
Note that M_PI
is not part of the C standard, so you can use the equivalent, which compiles to the exact same code:
double M_PI = 4.0 * atan(1.0);
回答2:
To answer the second question; pow
is designed to perform arbitrary powers, but it shouldn't be surprising that there is a faster way to compute the answer when the power is constant. A single multiplication is fast (just a single processor instruction), whereas a call to pow
requires function call overhead (ignoring optimisation for now) and an iterative algorithm which repeatedly multiplies until it gets the answer. When you can see a mathematical shortcut to avoid such things, you use it.
来源:https://stackoverflow.com/questions/15421755/understanding-double-precision-operations-in-c