|
Integer or float? What to use for logic? |
Locutus266
Member #7,638
August 2006
|
Hello, I am developing a simple 2D pong clone, that has no scrolling or such. As of now, I am holding x/y coordinates and speed values of paddles or ball in floating point values. To display game objects on the screen, I convert these variables to integers. This is a simplified version of my main game loop:
Now, I could as easily do all the logic calculations with integers using the "cycles_done" variable and the modulo operator:
Of course, the result wouldn't be exactly the same. But I think using the modulo operator together with cycles_done is a way to time events such as positional updates. What do you think? I'd like your advise... Is the modulo method, I came up with a common technique and is it advisable concerning performance to use integers or is the floating-point approach a better one? Thanks for all your suggestions and your time! Best regards, |
HoHo
Member #4,534
April 2004
|
Does your target computers not have a FPU co-processor that you want to use integers? If so then fixed-point would probably be better. I wouldn't use ints for anything with variable speed, they don't have enough accuaricy. __________ |
ImLeftFooted
Member #3,935
October 2003
|
What kind of computer CPU doesn't have a FPU co-processor? Not one I'm going to be programming for any time soon... I recommend using floating point, it is teh bettar. |
Jonatan Hedborg
Member #4,886
July 2004
|
Use floats. IF (and only if) your code runs slowly, check it out in a profiler. It will not be the floats fault. Continue to use floats Premature optimization kills creativity!
|
HoHo
Member #4,534
April 2004
|
Quote: What kind of computer CPU doesn't have a FPU co-processor? Some starting from 486's they had FPU integrated into the CPU. On older CPU's it was an optional addon. __________ |
Jonatan Hedborg
Member #4,886
July 2004
|
I think that was a rhetorical question HoHo
|
Locutus266
Member #7,638
August 2006
|
Thanks for your input so far. I am using Allegro on a Linux-based handheld called GP2X. It has an ARM CPU and only does software floating point. I have ported my code to use Allegro's fixed point functions, but lately the idea of the modulo thing came to my mind. Does anybody know, if this technique is widely used? |
ImLeftFooted
Member #3,935
October 2003
|
I've used it before. But, btw, doesnt a modulo have the same performance hit as a floating point divide anyway? |
HoHo
Member #4,534
April 2004
|
Quote: It has an ARM CPU and only does software floating point Well, thats a whole different story. There indeed floating point can take quite a while to compute. First I'd try to run some profiling on the handheld. From the results you can see how long time is spent in the functions that use floats. If it is too much I'd try replacing them with allegro's fixed-point math. Basically it is quite similar to the modulo thing but more accurate and you won't have to write the code yourself __________ |
orz
Member #565
August 2000
|
I would not recommend the modulo-with-cycles_done aproach. Modulo can be slow (though there's ways to make if faster in some cases; compilers can even figure out some of them, some of the time). Furthermore, there is little benefit to only doing your physics only every X cycles - you could simply slow down the cycle rate instead, from 250 to 50. The only advantage is the ability to have some of your physics run more often than other bits of your physics, as you do there by having ball position update less often than ball speed. But that's only valuable if some of your physics is much slower than the rest and doesn't need updating very often at all. I would recommend the use of fixed point numbers on CPUs that lack good FPUs. Fixed point can improve performance a lot, and in some cases it can also improve stability and/or accuracy. Unfortunately, it can take more effort, and can produce weird bugs (mainly overflow issues). If your don't need much performance, floating point might work fine. You might also consider supporting either floating point or fixed point as a compile time option. If you're using C++, this could probably be achieved with a simple typedef for your own numeric type to either Allegro's fixed point class or to the normal floating point type. Something along the lines of: #define USE_ALLEGRO_FIXEDPOINT #if defined USE_ALLEGRO_FIXEDPOINT typedef fix MyReal; #else typedef float MyReal; #endif However, you also have to keep in mind the differences in the angle units (from radians to 256ths), at which point you might add more like this: #define USE_ALLEGRO_FIXEDPOINT #if defined USE_ALLEGRO_FIXEDPOINT typedef fix MyReal; const float RadiansPerAngleUnit_float = 256.0 / (3.14159265358979 * 2); const MyReal RadiansPerAngleUnit_real = fix(256.0 / (3.14159265358979 * 2)); const float AngleUnitsPerRadian_float = (3.14159265358979 * 2) / 256.0; const MyReal AngleUnitsPerRadians_real = fix((3.14159265358979 * 2) / 256.0); #else typedef float MyReal; const float RadiansPerAngleUnit_float = 1.0; const MyReal RadiansPerAngleUnit_real = 1.0; const float AngleUnitsPerRadian_float = 1.0; const MyReal AngleUnitsPerRadians_real = 1.0; #endif Or perhaps numbers for degrees instead if you prefer degrees. |
ImLeftFooted
Member #3,935
October 2003
|
If posts could receive star ratings, I would give the above post full stars. |
Locutus266
Member #7,638
August 2006
|
Hello orz, that was very helpful. Thank you for your insight knowledge. I might consider, decreasing the logic timer (to 50 times per sec instead of 250) and increase speeds to compensate. I am not working with angles, yet. My collision detection approach depends on the ball speed not getting higher than 1 (so it doesn't skip any pixels). I suppose, a solution based on vectors or trajectories would be better / more efficient, but I still have to do some math for that, I think. Is it advisable to round the values when converting floating point values to on-screen coordinates for drawing? Also, I do not fully understand your typedef statements. Allegro fixed point values have to be converted to integers using fixtoi() and related functionality, which isn't normally necessary for normal floats. I believe "fixed" and "float" cannot be treated the same way in all situations. For example, you cannot simply add an integer to a fixed point value, or do you? Best regards, |
orz
Member #565
August 2000
|
Quote: If posts could receive star ratings, I would give the above post full stars. Thanks. Locutus266: Quote: that was very helpful. Thank you for your insight knowledge. I might consider, decreasing the logic timer (to 50 times per sec instead of 250) and increase speeds to compensate. 250 is overkill for most purposes. 100 is quite likely to be more than enough. 50 might be plenty. Quote: I am not working with angles, yet. My collision detection approach depends on the ball speed not getting higher than 1 (so it doesn't skip any pixels). I suppose, a solution based on vectors or trajectories would be better / more efficient, but I still have to do some math for that, I think. Perhaps you don't need trig functions for your game. If so, that will simplify the conversion back and forth between floats and fixed point types. Quote: Is it advisable to round the values when converting floating point values to on-screen coordinates for drawing? Well, the advantages to explicitly rounding are often small, but the only disadvantage is that you have to type a few extra characters. Several kinds of rounding are common: Quote: Also, I do not fully understand your typedef statements. Allegro fixed point values have to be converted to integers using fixtoi() and related functionality, which isn't normally necessary for normal floats. I believe "fixed" and "float" cannot be treated the same way in all situations. For example, you cannot simply add an integer to a fixed point value, or do you? The confusion arises because Allegro has two different fixed point types. There is the "fixed" type, which is documented, and uses functions like fixtoi() etc. There is also a special "fix" type, which is only briefly mentioned in the docs. The "fix" type is a wrapper for "fixed" that uses C++ operator overloading to make it behave much like a regular floating point type. ie you can just add ints or floats to it or whatever you want, and it will (usually) figure out what you mean. "fix" is only available if you are compiling as C++. You still occaisonally have to be careful... C-style text output functions like printf and textprintf often accept typeless parameters, and therefore you might have to explicitly cast a "fix" to an int or float (like: int(my_fix) or float(my_fix) when using it with a "%d" or "%f". |
Locutus266
Member #7,638
August 2006
|
Thanks once more for your remarks. Since I am programming in good old C, I won't be able to use the "fix" type, I guess. I think, I'll just try out some of your suggestions. Best regards, |
|