I only noticed the integer limitation, not the do-not-divide one.

There still is a simple solution: implement arctan2 using CORDIC. A simple web search on CORDIC and atan2 should provide a number of interesting results. Note that this version returns only the angle, not the distance, since the distance is not needed.

For example:

Code:

/* Array of atan2(1, 1<<i)*2147483648/(2*Pi).
* This yields 2147483648 = 360 degrees.
*/
const int iangle[] = {
268435456, /* 45.00000000000000000000 degrees */
158466703, /* 26.56505117707799001892 degrees */
83729454, /* 14.03624346792647692439 degrees */
42502378, /* 7.12501634890179769144 degrees */
21333666, /* 3.57633437499735151732 degrees */
10677233, /* 1.78991060824606940116 degrees */
5339919, /* 0.89517371021107439155 degrees */
2670123, /* 0.44761417086055305115 degrees */
1335082, /* 0.22381050036853808449 degrees */
667543, /* 0.11190567706620689614 degrees */
333772, /* 0.05595289189380366762 degrees */
166886, /* 0.02797645261700367619 degrees */
83443, /* 0.01398822714226501639 degrees */
41722, /* 0.00699411367535291827 degrees */
20861, /* 0.00349705685070401126 degrees */
10430, /* 0.00174852842698044954 degrees */
5215, /* 0.00087426421369378026 degrees */
2608, /* 0.00043713210687233457 degrees */
1304, /* 0.00021856605343934784 degrees */
652, /* 0.00010928302672007150 degrees */
326, /* 0.00005464151336008544 degrees */
163, /* 0.00002732075668004893 degrees */
81, /* 0.00001366037834002524 degrees */
41, /* 0.00000683018917001272 degrees */
20, /* 0.00000341509458500637 degrees */
10, /* 0.00000170754729250319 degrees */
5, /* 0.00000085377364625159 degrees */
3, /* 0.00000042688682312580 degrees */
1, /* 0.00000021344341156290 degrees */
1, /* 0.00000010672170578145 degrees */
0
};
static int iatan2(int y, int x)
{
size_t i = 0;
int angle, direction;
/* Which half-plane? */
if (y < 0) {
x = -x;
y = -y;
angle = -1073741824;
} else
angle = 0;
/* Which quadrant? */
if (x < 0) {
x = -x;
angle += 1073741824;
direction = -1;
} else
direction = +1;
/* Which octant? */
if (y > x) {
const int oldy = y;
y = x;
x = oldy;
angle += direction * 536870912;
direction = -direction;
}
/* Along axis? */
if (y == 0)
return angle;
/* Diagonal? */
if (y == x)
return angle + direction * 268435456;
/* Scale, for optimum results. x > y > 0.
* If coordinates are < 32768 in magnitude,
* you could just multiply by 32768.
*/
while (x < 268435456) {
x *= 2;
y *= 2;
}
/* Adjust direction. */
if (direction < 0)
y = -y;
/* CORDIC for angle, 0 < y < x. */
while (iangle[i]) {
const int oldx = x;
const int oldy = y;
if (y > 0) {
x += (oldy >> i);
y -= (oldx >> i);
angle += iangle[i++];
} else
if (y < 0) {
x -= (oldy >> i);
y += (oldx >> i);
angle -= iangle[i++];
} else
break;
}
return angle;
}

*iatan2(y,x)* yields angles [-536870912, 536870912], analogously to *atan2(y,x)* returning angles [-Pi, Pi], so each unit is 360/1073741824 degrees; one degree is about 2982616 units.

For x=-32768..32768, y=-32768..32768, the absolute error in angles is -13 to 13 units; i.e. the error of *iatan2(y,x)* is less than 0.00000436 degrees.

By the way, this is NOT optimized code. This, too, is in public domain, so you can do whatever you want with it.