<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>Integer or float? What to use for logic?</title>
		<link>http://www.allegro.cc/forums/view/589230</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Tue, 26 Dec 2006 01:42:29 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Hello,</p><p>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.</p><p>This is a simplified version of my main game loop:</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="k1">while</span> <span class="k2">(</span><span class="k3">!</span>game_over<span class="k2">)</span></td></tr><tr><td class="number">2</td><td><span class="k2">{</span></td></tr><tr><td class="number">3</td><td>  <span class="k1">if</span> <span class="k2">(</span>blit_buffer<span class="k2">)</span></td></tr><tr><td class="number">4</td><td>  <span class="k2">{</span></td></tr><tr><td class="number">5</td><td>    <span class="c">//Page flipping</span></td></tr><tr><td class="number">6</td><td>    <a href="http://www.allegro.cc/manual/show_video_bitmap" target="_blank"><span class="a">show_video_bitmap</span></a><span class="k2">(</span>screen_buffer<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">7</td><td>&#160;</td></tr><tr><td class="number">8</td><td>    <span class="k1">if</span> <span class="k2">(</span>screen_buffer <span class="k3">=</span><span class="k3">=</span> page1<span class="k2">)</span></td></tr><tr><td class="number">9</td><td>      screen_buffer <span class="k3">=</span> page2<span class="k2">;</span></td></tr><tr><td class="number">10</td><td>    <span class="k1">else</span></td></tr><tr><td class="number">11</td><td>      screen_buffer <span class="k3">=</span> page1<span class="k2">;</span></td></tr><tr><td class="number">12</td><td>&#160;</td></tr><tr><td class="number">13</td><td>    <a href="http://www.allegro.cc/manual/clear_to_color" target="_blank"><span class="a">clear_to_color</span></a><span class="k2">(</span>screen_buffer, black<span class="k2">)</span><span class="k2">;</span> <span class="c">//Reset memory bitmap to blackness.</span></td></tr><tr><td class="number">14</td><td>    blit_buffer <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span></td></tr><tr><td class="number">15</td><td>  <span class="k2">}</span></td></tr><tr><td class="number">16</td><td>&#160;</td></tr><tr><td class="number">17</td><td>  poll_user_input<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">18</td><td>&#160;</td></tr><tr><td class="number">19</td><td>  <span class="k1">while</span> <span class="k2">(</span>pending_cycles <span class="k3">&gt;</span> <span class="n">0</span><span class="k2">)</span> <span class="c">//Timer at 250 times per sec</span></td></tr><tr><td class="number">20</td><td>  <span class="k2">{</span></td></tr><tr><td class="number">21</td><td>    <span class="c">//Logic stuff using floating point</span></td></tr><tr><td class="number">22</td><td>    </td></tr><tr><td class="number">23</td><td>    ball.x <span class="k3">=</span> ball.x <span class="k3">+</span> ball.x_speed<span class="k2">;</span> <span class="c">//These are all floats that get converted into integers (pixels) by the drawing functions</span></td></tr><tr><td class="number">24</td><td>    ball.y <span class="k3">=</span> ball.y <span class="k3">+</span> ball.y_speed<span class="k2">;</span></td></tr><tr><td class="number">25</td><td>    </td></tr><tr><td class="number">26</td><td>    ball.x_spd <span class="k3">+</span><span class="k3">=</span> <span class="n">0</span>.<span class="n">01f</span><span class="k2">;</span> <span class="c">//Ball gets faster with time</span></td></tr><tr><td class="number">27</td><td>    ball.y_spd <span class="k3">+</span><span class="k3">=</span> <span class="n">0</span>.<span class="n">01f</span><span class="k2">;</span></td></tr><tr><td class="number">28</td><td>    </td></tr><tr><td class="number">29</td><td>    pending_cycles--<span class="k2">;</span></td></tr><tr><td class="number">30</td><td>    cycles_done<span class="k3">+</span><span class="k3">+</span><span class="k2">;</span> <span class="c">//Overall cycles done since game startup</span></td></tr><tr><td class="number">31</td><td>  <span class="k2">}</span></td></tr><tr><td class="number">32</td><td>&#160;</td></tr><tr><td class="number">33</td><td>  <span class="c">//Rendering</span></td></tr><tr><td class="number">34</td><td>  <span class="k1">if</span> <span class="k2">(</span>pending_frames <span class="k3">&gt;</span> <span class="n">0</span><span class="k2">)</span> <span class="c">//Timer usually at 60 fps</span></td></tr><tr><td class="number">35</td><td>  <span class="k2">{</span></td></tr><tr><td class="number">36</td><td>    draw_stuff_to_screen<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">37</td><td>&#160;</td></tr><tr><td class="number">38</td><td>    pending_frames--<span class="k2">;</span></td></tr><tr><td class="number">39</td><td>    blit_buffer <span class="k3">=</span> <span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">40</td><td>  <span class="k2">}</span></td></tr><tr><td class="number">41</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>

Now, I could as easily do all the logic calculations with integers using the &quot;cycles_done&quot; variable and the modulo operator:</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="k1">while</span> <span class="k2">(</span>pending_cycles <span class="k3">&gt;</span> <span class="n">0</span><span class="k2">)</span> <span class="c">//Timer at 250 times per sec</span></td></tr><tr><td class="number">2</td><td><span class="k2">{</span></td></tr><tr><td class="number">3</td><td>  <span class="c">//Logic stuff using floating point</span></td></tr><tr><td class="number">4</td><td>  </td></tr><tr><td class="number">5</td><td>  <span class="k1">static</span> <span class="k1">int</span> ball_speed <span class="k3">=</span> <span class="n">10</span><span class="k2">;</span> <span class="c">//10 in the beginning</span></td></tr><tr><td class="number">6</td><td>  </td></tr><tr><td class="number">7</td><td>  </td></tr><tr><td class="number">8</td><td>  <span class="k1">if</span> <span class="k2">(</span>cycles_done % ball_speed <span class="k3">=</span><span class="k3">=</span> <span class="n">0</span><span class="k2">)</span> <span class="c">//Every tenth cycle, do...</span></td></tr><tr><td class="number">9</td><td>  <span class="k2">{</span></td></tr><tr><td class="number">10</td><td>    ball.x <span class="k3">=</span> ball.x <span class="k3">+</span> ball.x_speed<span class="k2">;</span> <span class="c">//In this version, x and y speed are -1, 0 or 1</span></td></tr><tr><td class="number">11</td><td>    ball.y <span class="k3">=</span> ball.y <span class="k3">+</span> ball.y_speed<span class="k2">;</span></td></tr><tr><td class="number">12</td><td>  <span class="k2">}</span></td></tr><tr><td class="number">13</td><td>  </td></tr><tr><td class="number">14</td><td>  <span class="k1">if</span> <span class="k2">(</span>cycles_done % <span class="n">5</span><span class="k2">)</span> <span class="c">//every 5th cycle...</span></td></tr><tr><td class="number">15</td><td>    ball_speed <span class="k3">-</span><span class="k3">-</span><span class="k2">;</span></td></tr><tr><td class="number">16</td><td>  </td></tr><tr><td class="number">17</td><td>  pending_cycles--<span class="k2">;</span></td></tr><tr><td class="number">18</td><td>  cycles_done<span class="k3">+</span><span class="k3">+</span><span class="k2">;</span> <span class="c">//Overall cycles done since game startup</span></td></tr><tr><td class="number">19</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>

Of course, the result wouldn&#39;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&#39;d like your advise...</p><p>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?</p><p>Thanks for all your suggestions and your time!</p><p>Best regards,<br />Christoph B.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Locutus266)</author>
		<pubDate>Fri, 22 Dec 2006 17:00:53 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>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&#39;t use ints for anything with variable speed, they don&#39;t have enough accuaricy.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (HoHo)</author>
		<pubDate>Fri, 22 Dec 2006 17:05:09 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>What kind of computer CPU doesn&#39;t have a FPU co-processor?  Not one I&#39;m going to be programming for any time soon...</p><p>I recommend using floating point, it is teh bettar.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (ImLeftFooted)</author>
		<pubDate>Fri, 22 Dec 2006 17:11:01 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>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 <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" /></p><p>Premature optimization kills creativity!
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Jonatan Hedborg)</author>
		<pubDate>Fri, 22 Dec 2006 17:12:42 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
What kind of computer CPU doesn&#39;t have a FPU co-processor?
</p></div></div><p>Some starting from 486&#39;s they had FPU integrated into the CPU. On older CPU&#39;s it was an optional addon.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (HoHo)</author>
		<pubDate>Fri, 22 Dec 2006 17:22:40 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I think that was a rhetorical question HoHo <img src="http://www.allegro.cc/forums/smileys/wink.gif" alt=";)" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Jonatan Hedborg)</author>
		<pubDate>Fri, 22 Dec 2006 17:24:18 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Thanks for your input so far.</p><p>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&#39;s fixed point functions, but lately the idea of the modulo thing came to my mind.</p><p>Does anybody know, if this technique is widely used?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Locutus266)</author>
		<pubDate>Fri, 22 Dec 2006 17:40:08 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I&#39;ve used it before.  But, btw, doesnt a modulo have the same performance hit as a floating point divide anyway?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (ImLeftFooted)</author>
		<pubDate>Fri, 22 Dec 2006 17:46:22 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
It has an ARM CPU and only does software floating point
</p></div></div><p>Well, thats a whole different story. There indeed floating point can take quite a while to compute. First I&#39;d try to run some <a href="http://www.cs.utah.edu/dept/old/texinfo/as/gprof.html">profiling</a> 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&#39;d try replacing them with allegro&#39;s fixed-point math. Basically it is quite similar to the modulo thing but more accurate and you won&#39;t have to write the code yourself <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (HoHo)</author>
		<pubDate>Fri, 22 Dec 2006 17:47:31 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I would not recommend the modulo-with-cycles_done aproach.  Modulo can be slow (though there&#39;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&#39;s only valuable if some of your physics is much slower than the rest and doesn&#39;t need updating very often at all.  </p><p>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&#39;t need much performance, floating point might work fine.  </p><p>You might also consider supporting either floating point or fixed point as a compile time option.  If you&#39;re using C++, this could probably be achieved with a simple typedef for your own numeric type to either Allegro&#39;s fixed point class or to the normal floating point type.  Something along the lines of:
</p><div class="source-code snippet"><div class="inner"><pre><span class="p">#define USE_ALLEGRO_FIXEDPOINT</span>
<span class="p">#if defined USE_ALLEGRO_FIXEDPOINT</span>
  <span class="k1">typedef</span> fix MyReal<span class="k2">;</span>
<span class="p">#else</span>
  <span class="k1">typedef</span> <span class="k1">float</span> MyReal<span class="k2">;</span>
<span class="p">#endif</span>
</pre></div></div><p>

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:
</p><div class="source-code snippet"><div class="inner"><pre><span class="p">#define USE_ALLEGRO_FIXEDPOINT</span>
<span class="p">#if defined USE_ALLEGRO_FIXEDPOINT</span>
  <span class="k1">typedef</span> fix MyReal<span class="k2">;</span>
  <span class="k1">const</span> <span class="k1">float</span> RadiansPerAngleUnit_float <span class="k3">=</span> <span class="n">256</span>.<span class="n">0</span> <span class="k3">/</span> <span class="k2">(</span><span class="n">3</span>.<span class="n">14159265358979</span> <span class="k3">*</span> <span class="n">2</span><span class="k2">)</span><span class="k2">;</span>
  <span class="k1">const</span> MyReal RadiansPerAngleUnit_real <span class="k3">=</span> fix<span class="k2">(</span><span class="n">256</span>.<span class="n">0</span> <span class="k3">/</span> <span class="k2">(</span><span class="n">3</span>.<span class="n">14159265358979</span> <span class="k3">*</span> <span class="n">2</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
  <span class="k1">const</span> <span class="k1">float</span> AngleUnitsPerRadian_float <span class="k3">=</span> <span class="k2">(</span><span class="n">3</span>.<span class="n">14159265358979</span> <span class="k3">*</span> <span class="n">2</span><span class="k2">)</span> <span class="k3">/</span> <span class="n">256</span>.<span class="n">0</span><span class="k2">;</span>
  <span class="k1">const</span> MyReal AngleUnitsPerRadians_real <span class="k3">=</span> fix<span class="k2">(</span><span class="k2">(</span><span class="n">3</span>.<span class="n">14159265358979</span> <span class="k3">*</span> <span class="n">2</span><span class="k2">)</span> <span class="k3">/</span> <span class="n">256</span>.<span class="n">0</span><span class="k2">)</span><span class="k2">;</span>
<span class="p">#else</span>
  <span class="k1">typedef</span> <span class="k1">float</span> MyReal<span class="k2">;</span>
  <span class="k1">const</span> <span class="k1">float</span> RadiansPerAngleUnit_float <span class="k3">=</span> <span class="n">1</span>.<span class="n">0</span><span class="k2">;</span>
  <span class="k1">const</span> MyReal RadiansPerAngleUnit_real <span class="k3">=</span> <span class="n">1</span>.<span class="n">0</span><span class="k2">;</span>
  <span class="k1">const</span> <span class="k1">float</span> AngleUnitsPerRadian_float <span class="k3">=</span> <span class="n">1</span>.<span class="n">0</span><span class="k2">;</span>
  <span class="k1">const</span> MyReal AngleUnitsPerRadians_real <span class="k3">=</span> <span class="n">1</span>.<span class="n">0</span><span class="k2">;</span>
<span class="p">#endif</span>
</pre></div></div><p>

Or perhaps numbers for degrees instead if you prefer degrees.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (orz)</author>
		<pubDate>Sat, 23 Dec 2006 07:58:02 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>If posts could receive star ratings, I would give the above post full stars.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (ImLeftFooted)</author>
		<pubDate>Sat, 23 Dec 2006 10:17:22 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Hello orz,</p><p>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.</p><p>I am not working with angles, yet. My collision detection approach depends on the ball speed not getting higher than 1 (so it doesn&#39;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.</p><p>Is it advisable to round the values when converting floating point values to on-screen coordinates for drawing?</p><p>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&#39;t normally necessary for normal floats. I believe &quot;fixed&quot; and &quot;float&quot; 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?</p><p>Best regards,<br />Christoph B.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Locutus266)</author>
		<pubDate>Sat, 23 Dec 2006 22:29:14 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
If posts could receive star ratings, I would give the above post full stars.
</p></div></div><p>
Thanks.  </p><p>Locutus266:
</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
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.
</p></div></div><p>

250 is overkill for most purposes.  100 is quite likely to be more than enough.  50 might be plenty.  </p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
I am not working with angles, yet. My collision detection approach depends on the ball speed not getting higher than 1 (so it doesn&#39;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.
</p></div></div><p>

Perhaps you don&#39;t need trig functions for your game.  If so, that will simplify the conversion back and forth between floats and fixed point types.  </p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
Is it advisable to round the values when converting floating point values to on-screen coordinates for drawing?
</p></div></div><p>
Well, the advantages to explicitly rounding are often small, but the only disadvantage is that you have to type a few extra characters.  </p><p>Several kinds of rounding are common:<br />1.  float -&gt; int (i.e. (int)my_float or int(my_float)) normally rounds towards zero i.e. 1.9 becomes 1, -1.9 becomes -1 (This is slightly obnoxious when a move objects coordinates pass an axi, because the rounding hickups... the object can move almost 2 pixels while still appearing in the same spot instead of the usual almost 1 pixel.  Still, a pretty minor issue, not worth noticing in most cases.)<br />2.  fixtoi(fixed) or fix -&gt; int rounds to the nearest integer value, or towards positive infinity if two integers are equally close. i.e. 1.5 becomes 2, 1.49 becomes 1, -1.5 becomes -1, -1.51 becomes -2.  <br />3.  Other rounding methods are possible, but require more work and are usually slower.  There are a few rounding methods that are faster than the regular ones, but they generally either aren&#39;t much faster or have drawbacks, and I&#39;m not going in to them here as you don&#39;t really need them and this post will be big enough anyway.  </p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
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&#39;t normally necessary for normal floats. I believe &quot;fixed&quot; and &quot;float&quot; 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?
</p></div></div><p>
The confusion arises because Allegro has two different fixed point types.  There is the &quot;fixed&quot; type, which is documented, and uses functions like fixtoi() etc.  There is also a special &quot;fix&quot; type, which is only briefly mentioned in the docs.  The &quot;fix&quot; type is a wrapper for &quot;fixed&quot; 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.  &quot;fix&quot; 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 &quot;fix&quot; to an int or float (like: int(my_fix) or float(my_fix) when using it with a &quot;%d&quot; or &quot;%f&quot;.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (orz)</author>
		<pubDate>Sat, 23 Dec 2006 23:49:54 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Thanks once more for your remarks. Since I am programming in good old C, I won&#39;t be able to use the &quot;fix&quot; type, I guess.</p><p>I think, I&#39;ll just try out some of your suggestions.</p><p>Best regards,<br />Christoph B.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Locutus266)</author>
		<pubDate>Tue, 26 Dec 2006 01:42:29 +0000</pubDate>
	</item>
</rss>
