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.

Coding > fixed point math

#5479 - Daikath - Tue Apr 29, 2003 3:19 pm

I just can't seem to grasp the principles of fixed point math.

I've read this and this this tutorial and I gues I'm not into the right coder mindset yet since I still dont get it.

Could someone explain it to me like I am a 4 year old? (:P), it would be greatly appreciated.
_________________
?There are no stupid questions but there are a LOT of inquisitive idiots.?

#5482 - peebrain - Tue Apr 29, 2003 4:59 pm

Sure thing... it's easy. What you're doing is basically putting a denominator on every number you use. This denominator is constant, so you can cut some short cuts. Like for example, say that our denominator is 10. If we want to represent 45.7, we would put 457 in the variable. If we wanted 32, we would put 320 into the variable. Let's say we're now adding numbers:

45.7 + 32 = 77.7
457 + 320 = 777

Coincidence? I think not. So adding fixed point numbers is easy - just add! Think about it this way:

457 / 10 + 320 / 10 = (457 + 320) / 10 = 777 / 10

What about multiplication?

457 / 10 * 320 / 10 = (457 * 320) / (10 * 10) = 146240 / 100

But unfortunately, our constant denominator is 10, not 100, so we have to factor out a 10 so we get:

14624 / 10 = 1462.4

Which means? When multiplying two fixed point numbers we have to make sure to do that factoring step.

Ok so why do this? Integers are way faster than float's. Also, we can pick our denominator wisely so it's super fast. 10 isn't such a good choice when working on computers - something with the power of 2 let's us bit-shift instead of actually dividing. So like if we have 16 bits to mess with, you might do 8 bits for the number, 8 bits for the decimal (which would mean our denominator is 256).

That make any sense?

~Sean
_________________
http://www.pbwhere.com

#5483 - Daikath - Tue Apr 29, 2003 5:05 pm

It almost makes sense :), thanks though I finally get it, now I can look at the code and see how it works in there.

The only bit im puzzled about it how is it transfered to the actual variables? 77.7 or 777? And if it is 777 how is it made 77.7 in the variable?

It's frustrating to have code and not know how it works.

Thanks Sean :)
_________________
?There are no stupid questions but there are a LOT of inquisitive idiots.?

#5486 - peebrain - Tue Apr 29, 2003 5:58 pm

The variable holds the value 777, but you, the programmer, think of it as 77.7. The computer just thinks it's 777. You have to do the special work to make sure when you interpret that number, that you remember that 777 MEANS 77.7. So say that you're using this fixed point to represent how much cash you have. You choose a denominator of 100 because there are 100 pennies in a dollar. So let's say you have 500.34 bucks. The variable in memory will be 50034 ( = 500.34 * 100). Now let's say if you go below 150 bucks then you get kicked out of your bank or something. You won't write:
if cash < 150 then panic;
You will write:
if cash < 15000 then panic;
It's up to YOU, the programmer, to keep all that shit straight. It's usually worth it though for the speed increase.

~Sean
_________________
http://www.pbwhere.com

#5494 - Daikath - Tue Apr 29, 2003 7:42 pm

Heh, it sounds so simple now :). Everyone explains it too much so they forget the basics :), thanks.
_________________
?There are no stupid questions but there are a LOT of inquisitive idiots.?

#5495 - tepples - Tue Apr 29, 2003 7:43 pm

In practice, fixed-point usually uses a denominator of a power of 2 (such as 256), so that the adjustment after division or multiplication is a matter of a shift operation. Exceptions include (as peebrain alluded to) finance.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#5497 - Torlus - Tue Apr 29, 2003 8:01 pm

As examples before illustrate what are the basics of fixed point math, let's see how it can be used for "efficient" programming.
If you need to store "decimal" values in your GBA program, you can for instance consider that for a 32-bit value, you will store the "decimal" part in the 8 last bits, and the "integer" part in the 24 first bits remaining.
Of course your "decimals" are not negative powers of 10 (10^-1 = 0.1, 10^-2 = 0.0.1) but negative powers of 2 (2^-1 = 0.5, 2^-2 = 0.25...), which gives you in this case a precision of (2^-8). It can then speed up the code, as you will be able to get some math functions by performing arithmetic shifts.

Here are some macros I often use :

#define PRECISION 8

#define int2fp(x) ((x)<<PRECISION)
#define fp2int(x) ((x)>>PRECISION)

#define fpMul(x,y) (((x)*(y))>>(PRECISION<<1))

And if you're not still familiar with that kind of operation you can use something like :

#define fp int

And then manipulate "fp" and "int" as two different types.

Then, peerbrain's example could be written as follow :

fp cash;
cash = int2fp(100);
if (cash < int2fp(150)) then panic;

Then if you need more or less precision you just have to determine how many bits you need for "decimal" and "integer" part. If you need more precision, just increase the PRECISION value.
Of course there are overflow drawbacks (esepcially with a multiply operation).
_________________
GBA,GC,NGPC,GP32,FPGA,DS stuff at http://torlus.com/

#5498 - Daikath - Tue Apr 29, 2003 8:12 pm

Torlus wrote:
Of course your "decimals" are not negative powers of 10 (10^-1 = 0.1, 10^-2 = 0.0.1) but negative powers of 2 (2^-1 = 0.5, 2^-2 = 0.25...), which gives you in this case a precision of (2^-8). It can then speed up the code, as you will be able to get some math functions by performing arithmetic shifts.


Uhm.. Sorry but I gues this is the part where I tend to loose focus.

Though I can speak English well I didn't learn mathematics in them and I think that is what is confusing me with the other tutorials. Or maybe im not too experienced of a coder since I do not know what ^ means as a mathematic symbol :). Still thanks though :).
_________________
?There are no stupid questions but there are a LOT of inquisitive idiots.?

#5500 - Torlus - Tue Apr 29, 2003 9:08 pm

"^" means "power"... so 10^1 = 10, 10^2 = (10*10) = 100, 10^3 = (10*10*10) = 1000 etc.
for understanding negative powers, just admit that X^a * X^b = X^(a+b) (or read a math book:))
so for instance (10^-2) * (10^2) = 10^0 = 1, so it means that as 10^2 = 100, 10^-2 = 0.01
sorry it there are some math teachers here :)
_________________
GBA,GC,NGPC,GP32,FPGA,DS stuff at http://torlus.com/