14

两点之间的距离:

sqrt((x1-x2)^2 + (y1-y2)^2)

有没有办法在 Objective-C 中更快地完成这个数学?

编辑:我想我需要在上面澄清一下。我写上面的公式只是为了澄清我用来计算距离的公式。^ 并不是要代表 xor - 我只是想代表数学公式而不使用任何函数,如 pow 或任何东西,所以我打算使用 ^ 来“提高电源关闭”。我想知道是否有人知道使用按位运算符,或者在汇编中编写代码是否会提供优化版本。我在 iPhone / iPad 应用程序中使用该公式。

4

5 回答 5

36

不,如果您需要确切的距离,您无法击败该公式。

虽然要明确 ^ 不是求平方的运算符,而是进行异或的位运算符。

你将需要类似的东西

double dx = (x2-x1);
double dy = (y2-y1);
double dist = sqrt(dx*dx + dy*dy);

如果您可以只使用正方形(当您只想按距离排序时,这很有用,您可以使用更有效的

double dx = (x2-x1);
double dy = (y2-y1);
double dist = dx*dx + dy*dy;

这些至少和解决方案一样好。在最坏的情况下, pow() 将使用堆栈并且效率较低,但是对于这种情况,您的编译器可能会将其转换为 x*x 。

于 2012-02-02T06:56:01.890 回答
8

只是将其作为一个简单、美观的解决方案提供。它很可能不会比以前给出的任何更快,只是更短。我个人正在使用hypot.

double dist = hypot((x1-x2), (y1-y2));

根据文档,这将返回“(x^2+y^2) 的平方根”。

于 2014-10-07T21:22:04.503 回答
7

在 Intel Mac 上,Clang 将编译:

double distance = ({double d1 = x1 - x2, d2 = y1 - y2; sqrt(d1 * d1 + d2 * d2); });

总共有 6 条数学指令:sub、mul、sub、mul、add、sqrt;很难打败它。(sqrt 是一条指令,尽管它需要多个周期)。

于 2012-02-02T07:17:09.007 回答
3

这里唯一可以改进的是平方根计算功能。

我已经尝试了这两个函数(在关于平方根计算的维基百科文章中找到)来计算近似平方根值:

float fsqrt(float x)
{
  float xhalf = 0.5f * x;
  union
  {
    float x;
    int i;
  } u;

  u.x = x;
  u.i = 0x5f3759df - (u.i >> 1);
  x *= u.x * (1.5f - xhalf * u.x * u.x);

  return x;
}

float fsqrt2(float z)
{
    union
    {
        int tmp;
        float f;
    } u;

    u.f = z;

    /*
     * To justify the following code, prove that
     *
     * ((((val_int / 2^m) - b) / 2) + b) * 2^m = ((val_int - 2^m) / 2) + ((b + 1) / 2) * 2^m)
     *
     * where
     *
     * val_int = u.tmp
     * b = exponent bias
     * m = number of mantissa bits
     *
     * .
     */

    u.tmp -= 1 << 23; /* Subtract 2^m. */
    u.tmp >>= 1; /* Divide by 2. */
    u.tmp += 1 << 29; /* Add ((b + 1) / 2) * 2^m. */

    return u.f;
}

但在我的 Core 2 Duo Pentium CPU 上,它们似乎并不比 x87 FPUFSQRT指令快。看看它们是否比sqrtf()/sqrt()您平台上的标准工作得更快,以及准确性是否足够。

于 2012-02-03T06:26:49.063 回答
3
double dist = sqrt ( pow((x1-x2), 2) + pow((y1-y2), 2) );

考虑x1, x2, y1, y2floatdouble或整数。

于 2012-02-02T06:55:16.877 回答