问题
Distance between two points:
sqrt((x1-x2)^2 + (y1-y2)^2)
Is there a way to do this math faster in objective-C ?
EDIT: I think I need to clarify above. I wrote the formula above just to clarify what formula I am using to calculate the distance. ^ is not meant to represent xor - I just wanted to represent the mathematical formula without using any functions like pow or anything, so I meant to use ^ to "raise to the power off". I was wondering if anyone knows if using bitwise operators, or otherwise writing code in assembly would give an optimized version. I am using the formula in an iPhone / iPad application.
回答1:
No, if you need the exact distance you cannot beat that formula.
Although to be clear ^ is not an operator for squaring a value, but a bit operator that does xor.
you will need something like
double dx = (x2-x1);
double dy = (y2-y1);
double dist = sqrt(dx*dx + dy*dy);
If you can live with just the square (which is useful when you just want to do something like sort by distance, you can use the much more efficient
double dx = (x2-x1);
double dy = (y2-y1);
double dist = dx*dx + dy*dy;
These will be at least as good as a solution pow. At worst, pow() will use the stack and be less efficient, but maybe your compiler turns it into x*x for this case.
回答2:
Just offering this as a simple, nice looking solution. It is most likely not any faster than any previously given, just shorter. I personally am using hypot
.
double dist = hypot((x1-x2), (y1-y2));
Per the docs, this will return you "The square root of (x^2+y^2)."
回答3:
On an Intel Mac Clang will compile:
double distance = ({double d1 = x1 - x2, d2 = y1 - y2; sqrt(d1 * d1 + d2 * d2); });
into a grand total of 6 instructions for the maths: sub, mul, sub, mul, add, sqrt; pretty hard to beat that. (sqrt is a single instruction, though it takes multiple cycles).
回答4:
double dist = sqrt ( pow((x1-x2), 2) + pow((y1-y2), 2) );
considering x1, x2, y1, y2
are float
or double
or integer.
回答5:
About the only thing that can be improved here is the square root calculation function.
I've tried these two functions (found in a Wikipedia article on square root computation) to calculate approximate square root values:
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;
}
But on my Core 2 Duo Pentium CPU they don't seem to be faster than the x87 FPU FSQRT
instruction. See if they work faster than the standard sqrtf()/sqrt()
on your platform and if the accuracy is sufficient.
来源:https://stackoverflow.com/questions/9108208/fastest-way-to-calculate-the-distance-between-two-cgpoints