double r2 = dx * dx + dy * dy;
double r3 = r2 * sqrt(r2);
第二行可以用更快的东西代替吗?什么不涉及sqrt
?
答案 0 :(得分:14)
怎么样
double r3 = pow(r2,1.5);
如果将sqrt作为pow的特例实现,那将为您节省乘法。事情的宏伟计划中并没有太多的东西!
如果您真的想要提高效率,请考虑您是否真的需要r ^ 3。例如,如果您只是测试它(或从它派生的东西)以查看它是否超过某个阈值,那么测试r2,例如。
const double r3_threshold = 9;
//don't do this
if (r3 > r3_threshold)
....
//do do this
const double r2_threshold = pow(r3_threshold,2./3.);
if (r2 > r2_threshold)
....
那样pow
只会调用一次,甚至可能在编译时调用。
编辑如果你确实需要每次重新计算一次阈值,我认为有关Q_rsqrt的答案值得一看,可能值得超过这个
答案 1 :(得分:12)
使用fast inverse sqrt(执行Q_rsqrt
功能)。
你有:
float r2;
// ... r2 gets a value
float invsqrt = Q_rsqrt(r2);
float r3 = r2*r2*invsqrt; // x*x/sqrt(x) = x*sqrt(x)
注意:对于double
类型,有一个类似0x5f3759df
的常量可以帮助您编写一个处理double
数据类型的函数。
LATER EDIT:似乎已经讨论过该方法here。
LATER EDIT2: double
的常量位于维基百科link中:
Lomont指出,“神奇数字”为64位IEEE754大小 double double是0x5fe6ec85e7de30da,但实际上它接近于 0x5fe6eb50c7aa19f9。
答案 2 :(得分:1)
我认为另一种看待你问题的方法是“如何计算(或近似)sqrt(n)”。从那里你的问题将是微不足道的(n * sqrt(n))。当然,你必须定义你可以忍受多少错误。维基百科为您提供了许多选择:
http://en.wikipedia.org/wiki/Methods_of_computing_square_roots