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 > Urgent 16:16 fixed point division code requires

#19300 - corranga - Fri Apr 16, 2004 3:31 pm

Ok, I desperetly need 16:16 fixed point GBA division code to see if the rest of my code works. (My division doesn't seem to work properly!)

I don't care if it is in assembler or if it is just C code as long as it works (with as much of the 16:16 accuracy as possible!

Please help me before i pull my hair out!

Chris
_________________
If virtual reality is ever on a par with reality, I want to be Bomberman! :D

#19302 - jma - Fri Apr 16, 2004 3:54 pm

If you want something that you know works, just do this:

// return a/b (note: 24:8 fp math)
#define FIXDIV(a,b) ((a) << 8) / (b))

Jeff
_________________
massung@gmail.com
http://www.retrobyte.org

#19305 - shadow_gg - Fri Apr 16, 2004 6:20 pm

hum u wanna a 16:16 division code,
so u should have 32:32 number for the denominator,and a 16:16 for the numerator bcs 32:32 / 16:16 = 16:16

maybe u should get a 8:8 division code,
just divide a 16:16 by a 8:8 and u will have a 8:8 result

so u dont' need a function to do this just write it directly in ur code
hope it will help u
good luck !

#19306 - Miked0801 - Fri Apr 16, 2004 6:29 pm

Code:

s32 dividef1616(s32 f1, s32 f2)
{
    return Div((f1 * 64), (f2 / 64)) * 16;
}


Where Div is a call to the GBA BIOS divide.

If you don't know how to get that to work then:

Code:

s32 dividef1616(s32 f1, s32 f2)
{
    return ((f1 * 64) / (f2 / 64)) * 16;
}


This minimizes bit loss across both terms due to shifting. All terms are assumed to be Fixed 16:16.

#19330 - corranga - Sat Apr 17, 2004 3:34 pm

Thanks Miked0801, that worked although the accuracy isn't high enough.
(I'm working on wireframe 3d on the gba so accuracy is a bit of a must)

Chris
_________________
If virtual reality is ever on a par with reality, I want to be Bomberman! :D

#19338 - Miked0801 - Sat Apr 17, 2004 6:56 pm

Hmm. What kind of accuracy are you looking for? What kind of terms are you dividing? What kind of speed do you need? If you need every bit, you could do 2 divides - break the numerator into high/low 16-bits and divide each individually, shift and add terms when complete (kinda like when multiplying.) Of course, this is painfully slow. Another way would be to create a 64-bit divide in assembly and go that way. Still, I've never ever had need for that kind of accuracy which again begs the question of do you really need all those bits of accuracy? Losing a few bits on a divide shouldn't cause that much error unless you keep putting the error'd term back into the divide and do it again and again - at which point you will get noticable error.

#19350 - poslundc - Sat Apr 17, 2004 7:55 pm

Mike's division algorithm is accurate within approximately +/- 0.000122.

Or put another way, it only creates uncertainty in the bottom four bits of your 16-bit fractional portion.

How much precision do you really need?

Dan.

#19372 - corranga - Sun Apr 18, 2004 2:26 pm

Edit:
It is definetly the division code that isn't working properly,
An example of the calculation that is giving me troubles is:
34611200 / 1015360 = 2233965 (using windows fixed point code I wrote)
528.125 / 15.4931640625 = 34.0876007080078125
and
34611200 / 1015360 = -2097536 (using Mikes code)
528.125 / 15.4931640625 = -32.005859375 (note the negative, I presume meaning the signed bit is being changed?)

where the floating point answer should be 34.087614245194
although I now presume this is an overflow problem on the range side rather than an issue with accuracy?


Chris
_________________
If virtual reality is ever on a par with reality, I want to be Bomberman! :D

#19373 - corranga - Sun Apr 18, 2004 4:36 pm

Ok, fixed...
I just gave up a bit of accuracy for more range

Thanks for your help once more! :D
Chris
_________________
If virtual reality is ever on a par with reality, I want to be Bomberman! :D

#19376 - poslundc - Sun Apr 18, 2004 5:42 pm

Yes, it is a matter of overflow. There is always a trade-off to be made between precision and the maximum range of your variables.

It is a much bigger problem with division than multiplication, because you can always do long-multiplication (with the long long datatype or the MULL family of assembly instructions) in order to retain precision. Another good reason for using reciprocal look-up tables for division.

Dan.