For multiplication specifically (from #3):
This one is a bit more involved, but quite easy.
r = x * y
However, x and y don’t need to have the same format. The result will have a format containing the sum of both integer part’s bits and fractional part’s bits in x and y. For example if x is of the format 4.3 (4 bits for integer and 3 for fractional) and y is of the format 5.7, then the result will be of the format 9.10 (9 bits for integer part and 10 for fractional part).
Now we gotta think logically – if we, for example, have two numbers x and y in 8.8 format, then multiplying them will yield a 16.16 result. So, if we want a 8.8 result, we need to shift it right 8 bits. For the integer part, just ignore the upper bits, or do the same as if it overflowed (since you had a 16.16 format and now you want 8.8). Here’s an example:
// multiply fixed point number x with y, both are 8.8 format
// we want the result to be of 8.8 format too, so we need to shift right by 8
r = (x * y) >> 8
Meaning
ux = (x1 * COS - y1 * SIN) / TIMES;
uy = (x1 * SIN + y1 * COS) / TIMES;
Becomes:
ux = (((x1 * TIMES) * COS) / TIMES - ((y1 * TIMES) * SIN) / TIMES);
uy = (((x1 * TIMES) * SIN) / TIMES - ((y1 * TIMES) * COS) / TIMES);
Which can be simplified to:
ux = (((x1 * TIMES) * COS) - ((y1 * TIMES) * SIN)) / TIMES;
uy = (((x1 * TIMES) * SIN) - ((y1 * TIMES) * COS)) / TIMES;
Then to turn into an integer you’d divide by TIMES
again, giving
ux = ((((x1 * TIMES) * COS) - ((y1 * TIMES) * SIN)) / TIMES) / TIMES;
uy = ((((x1 * TIMES) * SIN) - ((y1 * TIMES) * COS)) / TIMES) / TIMES;
Which can be turned into:
ux = (((x1 * TIMES) * COS) - ((y1 * TIMES) * SIN)) / (TIMES * TIMES);
uy = (((x1 * TIMES) * SIN) - ((y1 * TIMES) * COS)) / (TIMES * TIMES);
Make sure the compiler is turning the multiplication and division into bitshifts though.