|
Fixed point math Displaying 1-5 of 5 total.
1
Beni
|
I read aen's tutorial, maybe I'm missing something, but I still don't understand how to do multiplication and division with 16.16 fixed point numbers.
This is the best I could come up with.
int FPmult(int a, int b)
{
return (a * (b>>16));
}
int FPdiv(int a, int b)
{
return (a / (b>>16));
}
But this leaves out the fractional part of b. Is there a better way?
Posted on 2004-11-24 08:24:30
|
basil
|
b>>16 is bitshifting DOWN, so you're dividing by a large number and losing information. The idea is that, for example,
10.1 * 4 = 40.4 which gets rounded down to 40. However, if you go
(10.1 * 10) * 4 = 404, no information has been lost. You just need to remember to divide back down by 10 when you use it.
And since bitshifting is just fast multiplication/division, it's the recommended way of doing this trick. Your multiply function will work if you bitshift UP, and the divide should look like (a<<16) / b. Just remember to shift the results back down when you use them.
Posted on 2004-11-24 10:10:22
|
Beni
|
An int is 32 bits right? So (a<<16) would cause the fractional part to move to the first 16 bits. And the whole part would just disappear right?
1.5 << 16 = 32768.0
32768.0 >> 16 = 0.5
1.5 becomes 0.5
I was thinking about it though and I have a better solution for the multiplication.
(a>>8) * (b>>8);
I'm still working on the division though.
Posted on 2004-11-25 01:23:54
|
basil
|
1.5 << 16
= 1.5 * (2^16)
= 98304
= my_result
my_result >> 16 = 1 because verge rounded down, but the precision is still there. For example:
(my_result *10) >> 16 = 15
And also,
(a>>8) * (b>>8)
= (a) * (2^8) * (b) * (2^8)
= (a) * (b) * (2^8)*(2^8)
= (a) * (b) * (2^16)
= (a)*(b) << 16
So by splitting it up like that you're doing the same thing but in two operations rather than one.
Just remember,
treat a << b as a*(2^b)
and a>>b as a/(2^b)
And remember that information right of the decimal point will be rounded off unless you multiply by a big enough number to get that information left of the decimal point. Confusing? Ask away if it is.
Posted on 2004-11-25 01:40:14 (last edited on 2004-11-25 01:42:42)
|
Beni
|
1.5 in fixed point notation lookes like this in binary
00000000000000011000000000000000
So 1.5 << 16 looks like this
110000000000000000000000000000000
But that is 33 bits. So the first bit will just fall off and it becomes this
10000000000000000000000000000000
Then when you shift down 16 again it becomes this
00000000000000001000000000000000
Which is 0.5 in fixed point notation.
Oh, by the way, it looks like I'm not paying attention to the first bit as the negative sign, but in my actual code, I've handled that. But I still need a good function for division.
Posted on 2004-11-25 03:18:50
|
Displaying 1-5 of 5 total.
1
|
|