两点之间的距离:
sqrt((x1-x2)^2 + (y1-y2)^2)
有没有一种更快的方法在Objective-C中进行这个数学计算?
编辑:我认为我需要澄清一下上面的内容。我写上面的公式只是为了澄清我正在使用的计算距离的公式。^并不表示异或 - 我只是想用数学公式表示,而不使用任何函数如pow等,所以我想使用^来代表“乘方”。我想知道是否有人知道使用位运算符,或以其他方式编写代码的汇编版本是否会得到优化。我在一个iPhone/iPad应用程序中使用这个公式。
两点之间的距离:
sqrt((x1-x2)^2 + (y1-y2)^2)
有没有一种更快的方法在Objective-C中进行这个数学计算?
编辑:我认为我需要澄清一下上面的内容。我写上面的公式只是为了澄清我正在使用的计算距离的公式。^并不表示异或 - 我只是想用数学公式表示,而不使用任何函数如pow等,所以我想使用^来代表“乘方”。我想知道是否有人知道使用位运算符,或以其他方式编写代码的汇编版本是否会得到优化。我在一个iPhone/iPad应用程序中使用这个公式。
不行,如果你需要准确的距离,那么你无法打败那个公式。
虽然需要明确的是,^ 不是用于对一个值进行平方运算的操作符,而是执行异或位运算的操作符。
你需要使用类似以下的内容:
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()函数一样好。在最坏的情况下,pow()会使用堆栈并且效率较低,但也有可能你的编译器会将其转换为x*x以提高效率。
pow
函数的执行时间至少比 *
运算符慢一个数量级,而且我认为编译器无法对 pow
进行优化,因为它不能确定 pow
是否已被替换为完全不同的函数。 - Mike Dunlaveyhypot(dx, dy)
。 - The Paramagnetic Croissant我提供一个简单、好看的解决方案。它可能不比之前提供的任何方法更快,只是更短。我个人正在使用 hypot
。
double dist = hypot((x1-x2), (y1-y2));
在Intel Mac上,Clang可以编译:
double distance = ({double d1 = x1 - x2, d2 = y1 - y2; sqrt(d1 * d1 + d2 * d2); });
double dist = sqrt ( pow((x1-x2), 2) + pow((y1-y2), 2) );
考虑到x1, x2, y1, y2
是float
、double
或整数。
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 FPU的FSQRT
指令更快。请检查它们是否在您的平台上比标准的sqrtf()/sqrt()
函数更快,并且精度是否足够。