13
double r2 = dx * dx + dy * dy;
double r3 = r2 * sqrt(r2);

第二行可以用更快的东西代替吗?不涉及的东西sqrt

4

3 回答 3

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 的答案值得一看,并且可能应该超过这个

于 2011-12-09T13:22:27.737 回答
12

使用快速逆 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。

于 2011-12-09T13:29:28.407 回答
1

我认为另一种看待您的问题的方法是“如何计算(或近似) sqrt(n) ”。从那里你的问题将是微不足道的(n * sqrt(n))。当然,你必须定义你可以忍受多少错误。维基百科为您提供了许多选择:

http://en.wikipedia.org/wiki/Methods_of_computing_square_roots

于 2011-12-09T13:36:47.040 回答