给定r ^ 2,是否有一种有效的方法来计算r ^ 3?

时间:2011-12-09 13:19:03

标签: c++ performance floating-point distance square-root

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

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

3 个答案:

答案 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