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 Rounding...

#10536 - regularkid - Mon Sep 08, 2003 5:03 am

I'm trying to round up some fixed point numbers (12.20). Since I can have positive or negative values, here is what I want to happen:

If the decimal part of the number is greater than 0.5 (2048), then:
If the number is positive, then add 2048
If the number is negative, then subtract 2048

Here is the direct translation of the above that I am currently using in my code:

Code:

if(num & 0x00000800)
{
    if(num > 0)
    {
        num += 2048;
    }
    else
    {
        num -= 2048;
    }
}
               
num >>= 12;


So, the above works and gives me what I want, but I would like to do it without the 'if's. I'm stumped...anyone have any good simple ways of rounding up fixed point numbers both negative and positive? Thanks!
_________________
- RegularKid

#10539 - DekuTree64 - Mon Sep 08, 2003 6:26 am

Are you sure it really matters? It will only make a difference when you're at exactly 2048. If you have say, 0x2750, add 0x800, and you get 0x2f50. Shift by 12 and you end up with 2. Then 0x2850 + 0x800 = 0x3050, >>12 = 3. Which is proper rounding. Then for negatives, if you have 0xd8b0 (-0x2750, 16-bit so it's easier to write, just imagine 4 f's before it), + 0x800 = 0xe0b0, >>12 = 0xfffe = -2, which is also properly rounded. And just for completeness, 0xd7b0 (-0x2850) + 0x800 = 0xdfb0, >>12 = fffd = -3. But 0x2800 + 0x800 = 0x3000, >>12 = 3, and 0xd800 (-0x2800) + 0x800 = 0xe000 >> 12 = -2. But right at an even half is the only place where negatives will round toward zero and positives will round away from zero, but actually since being at exactly 1/2 is like the old question about wether the glass is half empty or half full, where logically it could go either way, then I think it evens it out a little more.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#10545 - FluBBa - Mon Sep 08, 2003 11:26 am

hmmm, where to start...
say you want to round of -0.1 to a normal integer, that would be 0, right?
to represent this with a fixed point number with 12 bits for the fraction it would be something like -4096/10=-410=0xFFFFFE66.
If you don't do anything with the number before you shift it, it would become -1/0xFFFFFFFF, but if you add 2048 it will end up 0 which is right. I'm not so good with C but I think it will use an arithmetic shift if the type is signed.

C code:

Code:

if(num & 0x00000800)
{
        num += 2048;
}
num >>= 12;


Or if you're into assembler:
Code:

movs r0,r0,asr#12
addcs r0,r0,#1

_________________
I probably suck, my not is a programmer.

#10554 - regularkid - Mon Sep 08, 2003 5:58 pm

Thanks, guys!
_________________
- RegularKid