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 > More accurate fixed point divide

#63704 - keldon - Thu Dec 15, 2005 6:30 pm

Code:
inline int fpdiv ( int a, int b ) {
   int bs = ( b < 0 ? -1 : 1 );
   b *= bs;
   
   long long lb;
   lb = 1;
   lb = lb << 63;
   lb = lb / ((long long) b  );
   b = (int) (lb >> 31);
   
   return fpmul (a, b * bs );
   
}

Is there a more accurate way to perform fixed point division?

#63708 - DekuTree64 - Thu Dec 15, 2005 6:49 pm

Ideally you'd want
Code:
inline int fpdiv ( int a, int b ) {
    return (int) (((long long)a << FRACTION_BITS) / (long long)b);
}

That's gotta be slow, doing a 64-bit divide, but it's quite accurate.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#63716 - keldon - Thu Dec 15, 2005 7:50 pm

Oh yes it works a treat; thanks a lot

#64760 - keldon - Mon Dec 26, 2005 1:15 pm

Code:
inline int fpdiv ( int a, int b ) {
    return ((a << (FRACTION_BITS-1)) / b) << 1;
}


You can use an int by sacrificing one bit. I was using this for texture mapping and it has not hurt it a single bit. No pun intended.

#64783 - poslundc - Mon Dec 26, 2005 7:16 pm

keldon wrote:
Code:
inline int fpdiv ( int a, int b ) {
    return ((a << (FRACTION_BITS-1)) / b) << 1;
}


You can use an int by sacrificing one bit. I was using this for texture mapping and it has not hurt it a single bit. No pun intended.


You have not thought this through. Example:

FRACTION_BITS = 16
a = 256.5 (0x01008000)
b = 1.0 (0x00010000)
fpdiv(a, b) = 0.5 (0x00008000)

Just because it happens to work within the domain of your application's constraints doesn't mean it works universally.

Dan.

#64794 - keldon - Mon Dec 26, 2005 8:45 pm

Oh yes that was quite silly. It was only working because all of my numbers were less than 1. It needs to be long. Thanks for pointing that one out.