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.

Beginners > Overflow in fixed point calculation

#63232 - Ultima2876 - Sat Dec 10, 2005 10:02 am

Hey all.

When I do a fixed point calculation, such as:

score / 100000, = score * 0.00001, ~= (score * 168) >> 24.

That's fine, but what if score is a value that goes up to 999999? That calculation would need way more than 32 bits... would the GBA have to go into some slow software 64-bit mode, or would it simply lop off the upper bits (bad)? Or even some other magic solution that happens to solve my problem? I can't use 16 bit fixed point because, apart from having the same problem (to a lesser extent), it's not accurate enough.

This is more out of curiousity as to how the internals work more than anything, but info and/or ideas are appreciated nonetheless.

Thanks =P

#63234 - keldon - Sat Dec 10, 2005 10:09 am

Arm has 64 bit long multiplication
http://www.work.de/nocash/gbatek.htm#arm8multiplylongandmultiplyaccumulatelongmullmlal

#63235 - Ultima2876 - Sat Dec 10, 2005 10:27 am

o_O

Trying it, it seems like even 24 bits isn't accurate enough. Wierd. As for the 64 bit multiplication - cool, so I could try 32 bits as well... I'll look into that.

#63236 - DekuTree64 - Sat Dec 10, 2005 10:45 am

An easy way to use 64-bit mul:
Code:
#define fixedMul(a, b) ((s32)(((s64)(a) * (s64)(b)) >> FRAC_BITS))

The compiler should have enough sense to use smull instead of a series of 32-bit muls and additions. It will only be fast in ARM mode though, since THUMB has no umull/smull. I'm not sure if it would be faster to let the compiler emulate it with 32-bit multiplies, or to make a function compiled as ARM and call it.
Either way, if it's a tight enough loop to really matter, it should be ARM in IWRAM anyway.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku