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.

C/C++ > Advanced C++ topic covering templates and operator overloads

#2455 - animension - Tue Feb 04, 2003 9:45 am

Hi guys,

I'm trying to create a wrapper class for fixed point decimal operations such that numeric operations on the class would allow me to write code that closely resembles the use of floating point operations. I'll try to get down in writing exactly what it is I'm trying to do, but apologies beforehand if I end up sounding unclear.

I'd like to be able to specify the primitive type that the class wraps around in order to control storage requirements and memory overhead. Something like that is typically done with templates. The numeric operations on them would be a case of operator overloading. However, I'd also like to allow different instantiated class templates that have different primitive types the class wraps around interact with each other and with other primitives and constants.

What I'd like to see as an end result is being able to do something like the following:

Code:

Fixed<signed long int> fixedvar1 = 231.6521;
Fixed<unsigned char> fixedvar2 = 0.923;
unsigned short int var3 = 10;

// adding an unsigned short to Fixed<signed long int>
fixedvar += var3;

// adding a primitive float constant to Fixed<signed long int>
fixedvar += 22.528;

// multiplying Fixed<signed long int> by Fixed<unsigned char>
fixedvar *= fixedvar2;

// adding primitive unsigned short int to Fixed<signed long int> and returning a Fixed<unsigned char>
fixedvar2 = fixedvar1 + var3


Is there an elegant way to make the operator overloads take an ambigous Fixed<T> type (also primitive type) and add it to another Fixed<T> type and return an appropriate Fixed<T> type that is storing the resulting value?

I've tinkered around a bit with this idea but my implementations always end up having to declare argument types that are specific (Fixed<signed char> for example) for EACH operator overload, bloating my code. I'd imagine there's a way to do this by combining template classes, function templates, and operator overloads, but I can't seem to get the combination right.

If any C++ savvy person could point me in the right direction or heck, even recommend a book that extensively discusses the creation and use of class templates, function templates, etc, I'd be indebted.

Thanks!
_________________
"Beer is proof that God loves us and wants us to be happy."
-- Benjamin Franklin

#2481 - Vortex - Tue Feb 04, 2003 5:53 pm

Quote:
If any C++ savvy person could point me in the right direction or heck, even recommend a book that extensively discusses the creation and use of class templates, function templates, etc, I'd be indebted.


The best C++ book IMO is Bjarne Stroustrup's "The C++ Programming Language". I am sure you will be able to find your answers there.

#2484 - col - Tue Feb 04, 2003 8:09 pm

animension wrote:
Hi guys,

...

Code:

Fixed<signed long int> fixedvar1 = 231.6521;
Fixed<unsigned char> fixedvar2 = 0.923;
unsigned short int var3 = 10;

...


Is there an elegant way to make the operator overloads take an ambigous Fixed<T> type (also primitive type) and add it to another Fixed<T> type and return an appropriate Fixed<T> type that is storing the resulting value?
...
Thanks!


wow :)

When I started coding on gba, I started attempting what you're trying to do - however, I very soon gave up.

As I developed a better understanding of fixed point maths and of gba programming / ARM assembly, I realised that it was a pointless exercise.

the way the ARM chip works, fixed point math can be VERY quick - but converting floating point values into fixed is a slow process, and having a constructor called to initialise a fixedPoint is serious overkill!! (not to mention all that bloat.

After a while thinking/writing in fixed point becomes almost second nature.
I don't think you should worry about fixed point chars either - just extra added processing for the cpu!! - just stick to longs

For general code, pick a format (many use 24:8 - I chose 16:16) and stick to it, then all you have to do is remember to shift after a multiplication or divide, and shift to convert to integer math.

When you need to squeeze more precision out of your code, just keep track of the position of the imaginary point (in your comments?).

Whatever, its a nice idea wrapping fixed point - very oop - but IMO a complete waste of time on gba (cpu time and you time) - better wrapping the hardware ie sprites, backgrounds, DMA, Timers, interuppts etc. - if you've already done all that, write a game :)

Remember fixed point is (almost) as fast as using integers and almost as simple :)

cheers

col.

#2492 - animension - Tue Feb 04, 2003 9:58 pm

Col,

Thanks for the lengthy, thoughtful reply. I guess I just wanted to stick to OOP paradigms and write really elegant code. The flip side to that, as you say, is the sacrifice in efficiency which translates into a speed decrease.

If there isn't really much of a point in doing it, I won't pursue a solution. Nevertheless, for sheer academic value, it would be interesting to see a solution to a complex problem like that one all the same. :)

Cheers!
_________________
"Beer is proof that God loves us and wants us to be happy."
-- Benjamin Franklin