Understanding double precision operations in C

*爱你&永不变心* 提交于 2019-12-08 12:23:16

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!