double r2 = dx * dx + dy * dy;
double r3 = r2 * sqrt(r2);
第二行可以用更快的东西代替吗?不涉及的东西sqrt
?
double r2 = dx * dx + dy * dy;
double r3 = r2 * sqrt(r2);
第二行可以用更快的东西代替吗?不涉及的东西sqrt
?
怎么样
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 的答案值得一看,并且可能应该超过这个
使用快速逆 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
数据类型的函数。
稍后编辑:似乎该方法已经在这里讨论过。
稍后 EDIT2:的常量double
在维基百科链接中:
Lomont 指出,64 位 IEEE754 大小类型 double 的“幻数”是 0x5fe6ec85e7de30da,但实际上它接近于 0x5fe6eb50c7aa19f9。
我认为另一种看待您的问题的方法是“如何计算(或近似) sqrt(n) ”。从那里你的问题将是微不足道的(n * sqrt(n))。当然,你必须定义你可以忍受多少错误。维基百科为您提供了许多选择:
http://en.wikipedia.org/wiki/Methods_of_computing_square_roots