gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Patater's Introduction to Nintendo DS Programming > Fixed Point Number Primer

#165825 - the-anonymous-coward - Thu Jan 08, 2009 1:54 am

I am a bit confused. I am still learning C++, so this may seem a dumb question. I am looking at a line of code like "REG_BG3PA = 1 << 8;" and thinking that this is a bitwise operation, as in REG_BG3PA's binary value would now be ...1-0000-0000. Is that incorrect? Probably is.

But in the tutorial patater states that "<< 8" is a fixed point number, but I don't understand how it is represented. Is there an article or something that someone knows of that can clarify this for me?

I hope I explained my problem well enough. If someone doesn't understand just let me know and I will try to explain again.

#165828 - Dwedit - Thu Jan 08, 2009 3:02 am

"Fixed point" is nothing more that using multiples of some big integer.
It's like saying, "Let's always store a number as 256 times some number".
So say that 5.0 = 256*5 = 1280
Then say 3.0 = 256*3 = 768
5.0+3.0= 256*8 = 2048
Then when you want to get the integer part back, you divide by 256, and get 8.

The advantage of fixed point is that fractional numbers can be stored. 2.5 would be 256*2.5 = 640. Using 8 bits for the fractional part means you can have fractions from 1/256 to 255/256. But 0.1 would be 25.6/256, and the .6 gets clipped off, so you would either need to take 25/256 or 26/256 for that number.

"<<" is the left shift operator. "<< 8" is identical to "* 256".

The binary value you mentioned is indeed 1-0000-0000, and that is correct.

Addition and subtraction of fixed point numbers works just like regular addition and subtraction. Multiplying two fixed point numbers together requires you to shift the final result right by 8 afterwards to have a fixed point number that follows the same format as the arguments.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#165829 - the-anonymous-coward - Thu Jan 08, 2009 7:52 am

Oh, thanks a lot. That was a very helpful explanation. Perhaps patater could link this topic for further reading? It isn't that the tutorial was poorly written, it's just that I personally needed a bit more, and this did it. Plus, there may be others who need something like this to understand. Thanks again.

#165832 - sgeos - Thu Jan 08, 2009 8:56 am

Working through macros can make things more obvious for readers of your code:
Code:
/*** Fixed Point Macros
 */
// value = value before conversion
// bits = bits in fractional component
#define FLOAT2FIXED(value,bits) ((int)((value)*(1<<(bits))))
#define FIXED2FLOAT(value,bits) ((float)(value)/(1<<(bits)))
#define FIXED2INT(value,bits) ((value)>>(bits))

They are used like this:
Code:
/*** Examples Using PI
 */
fixed_t my_fixed = FLOAT2FIXED(    3.14159, 21);  // ==    6588391   == 0x006487E7
int     my_int   = FIXED2INT(   0x006487E7, 21);  // ==          3   == 0x00000003
float   my_float = FIXED2FLOAT( 0x006487E7, 21);  // == 3.14158964   (yes, fixed point numbers have major rounding errors)