|
||||||||||||||||||
Add Forum to Favorites | Send Topic To a Friend | View Forum FAQ | Track this topic |
Last Thread Next Thread ![]() |
| fixed point as a type |
|
![]() ErUs Member since: 4/22/2005 From: Catford, United Kingdom |
||||
|
|
||||
| im trying to implement a fixed point type like a float: typedef struct { long actual; long operator == (void) { return (actual>>1024); } } fint; have i got totaly the wrong idea? also im not too sure how todo the other operators. thanks |
||||
|
||||
![]() JohnBolton Member since: 4/3/2002 From: Belmont, CA, United States |
||||
|
|
||||
| I'm not sure if your idea is totally wrong, but it's pretty close. Implementing operator==() like that makes no sense. If you want to implement fixed point yourself, take a look at how other people have implemented it first: (Google: C++ fixed point library) John Bolton Locomotive Games (THQ) Current Project: Destroy All Humans (Wii). IN STORES NOW! |
||||
|
||||
![]() Ravyne Member since: 2/26/2007 From: Kirkland, WA, United States |
||||
|
|
||||
| If you're doing this to simply learn, then I wish you the best of luck. However I'll offer a word of warning if you're hoping that this will offer real-life speed benefits. I Implimented an entire fixed point class a year or two ago, and it turned out to be slower than standard floating point math. Firstly, the days whem floating-point calculations were vastly slower than integer calculations are well behind us (unless you're on a platform with no FPU, of course.) Its to the point now that any additional function overhead will more than kill what little difference there is. This brings me to point #2, fixed-point routines shouldn't be implimented as standard functions, let alone a class. By the time you push 2 opperands on the stack, do your "fast" fixed point calculation (which is little if any faster than floating point anyhow), and return the results, floating point has already passed you up and is now taking a leisurely nap in the sun. fixed-point only stands a chance if its inlined (and by that I mean actually GETS inlined) or as a pre-processor MACRO. Even if you get all this right, your performance could actually be worse on certain architectures and/or with certain algorithms. Floating point is REALLY fast these days. Intel, AMD, IBM, etc have all been working hard to improve floating point performance and leaving integer calculation alone for the most part. Some, if not many, modern CPUs are able to calculate more floating point instructions at once than they can integer instructions and certain parts needed for good fixed-point performance are weak, such as the P4's shift unit; In a relay you're only as fast as your slowest runner. Now, don't dispair, aside from platforms with no FPU there are some places where fixed point can be useful. If you can offload some otherwise-floating-point calculations to the Integer unit and still keep the FPU busy you should see some speedup, particularly if the Integer calcs are incremental (add & subtract), a classic example of this would be a triangle rasterizer that uses fixed point for the inner loop. Another good place is when you can tailor a new approach that playes to fixed-point's strength, like DDA or Bresenhams. But as I said before, there's no room here for the additional overhead that a class or function would incur, only raw code, light macros, or known-inlines need apply. As for how fixed point works, add and subtract are just that, assuming that the precision is the same. IE: to add or subtract two 24.8 floating point numbers, just add or subtract them. If you want to add or subtract different precisions, say subtract a 16.16 from a 24.8, you need to shift the 16.16 to the right 8 places. Basically, line up the decimal point and you're good, although you may have noticed that when shifting to the right, say 8 positions, you loose your least signifigant 8 bits of precision. If you shifted 8 to the left, you'd lose your 8 MOST signifigant bits of precision. Be carefull and watch your precision! As for multiply and divide, you have to shift right or left by half the number of decimal points in your equation. IE: if you multiply two 16.16 fixed point numbers you need to shift right 16 decimal places. This can be before, after, or both. When pre-shifting, you can shift by unmatched numbers, as long as they add up to half the total decimal places. For example, you could shift both right by 8, or one right by 16, or one by 12 and the other by 4. It will give you the same results (more or less) with the only difference due to precision issues. Again, its about managing precision and knowing your algorithm. If you know that one value shouldn't have a fractional part at all, shift it all the way to the decimal, this would give you the most accurate results. Another thing to watch for when multiplying is overflow/underflow, if you try to multiply very large numbers or divide a very small number by a very large number you can exceed the bounds of your register. You can alleviate this by pre-shifting your values, at the cost of precision. Once again it comes down to managing your precision, knowing how your algorithm behaves and what kinds of values your dealing with. This is another reason that a fixed-point class or functions fall short, often times you want to handle each situation slightly different... preshift both by 4 here, post shift by 8 there... its all very situational. Admittedly, inlines and macros do little to address this problem either. |
||||
|
||||
![]() Stary Member since: 11/2/2002 From: Stockholm, Sweden |
||||
|
|
||||
Quote: That's only true if you don't know how to use the language properly. Properly optimized code inlined in a class is on-par if not better than floating point math when it comes to performance - and of course that means it needs to get inlined, but so do many other things. Talking about function calls when it comes to these sort of data types is just silly. Also remember that fixed point sometimes has other uses - for instance, if you know your range ahead of time, fixed point can actually provide you with better accuracy than floating point does. |
||||
|
||||
![]() ErUs Member since: 4/22/2005 From: Catford, United Kingdom |
||||
|
|
||||
| im trying to implement a very simple 3d engine on the Ipod with ipodlinux www.ipodlinux.com the ipod uses an arm cpu which cant do natvie floating point stuff. I think i am going to write the engine completely in C now and use MACROs to do the switching between fixed point. thanks all |
||||
|
||||
![]() The_Incubator Member since: 1/6/2004 |
||||
|
|
||||
| Another practical use for fixed point is when data must be synchronized on multiple machines across a network. Say you're doing a multiplayer game and each machine broadcasts a set of values over the network and then every other machine needs to compute the exact same derived values from them. If you try to do this with floating point you will find that differences between Intel's and AMD's floating point implementations will throw you out of synch. Even different CPU models from the same manufacturer can behave differently, to say nothing of what happens when you want to allow people with Macs and PCs to play each other (oops, that's not such a big deal anymore). Definately not a job for floating point... At that point you may just say to hell with it, lets do everything with integers (which may not be a bad idea), but fixed point is a viable option. [Edited by - The_Incubator on June 14, 2006 2:43:14 PM] |
||||
|
||||
All times are ET (US)![]() |
Last Thread Next Thread ![]() |
|