<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>Saving Floats</title>
		<link>http://www.allegro.cc/forums/view/565997</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Thu, 16 Feb 2006 12:30:30 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Ok, so a while back, I think KittyCat had posted, a method of saving floats (can&#39;t find it now) that basically involved some division, seperating it into two peices, and then saving each peice individually... it was kind of complicated but only like 5 lines or so of code...  If anybody has any idea what I&#39;m talking about, reposting this code would be greatly appreciated...</p><p>The reason for it, instead of just saving 4 bytes from memory was for cross platform compatability... (not all compilers adhere to the same standards or some such...)</p><p>Anyway, the reason I want it is because I&#39;m writing a game in VB.NET (using allegro&#39;s file packing routines for saving data) that will save maps/tilesets to files on disk, and I need to save a single (a float is called a single in VB.) to a file. -- I&#39;ve written some string/bitmap saving functions that seem to work pretty good, but saving with single.ToString()/loading with Single.Parse(x) is probably pretty bad for accuracy...</p><p>Help!</p><p>EDIT:<br />got the post: <a href="http://www.allegro.cc/forums/thread/525662">http://www.allegro.cc/forums/thread/525662</a></p><div class="quote_container"><div class="title">Kitty Cat said:</div><div class="quote"><p>

To save a float/double:<br />pack_iputl(file, floor(fval));if(fval-floor(fval))   pack_iputl(file, 1/(fval-floor(fval)));else   pack_iputl(file, 0);<br />And to read:<br />long whole = pack_igetl(file);long recip = pack_igetl(file);float fval = whole + (recip ? (1.0/(float)recip) : 0.0);<br />Should work. To save an int, use pack_igetl/pack_iputl. For char, pack_getc/pack_putc.
</p></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Michael Jensen)</author>
		<pubDate>Sat, 11 Feb 2006 12:47:04 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><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">void</span> save_float<span class="k2">(</span><a href="http://www.allegro.cc/manual/PACKFILE" target="_blank"><span class="a">PACKFILE</span></a> <span class="k3">*</span>pf, <span class="k1">float</span> f<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">unsigned</span> <span class="k1">int</span> recip<span class="k2">;</span></td></tr><tr><td class="number">4</td><td>   <span class="k1">int</span> num <span class="k3">=</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_330.html" target="_blank">floor</a><span class="k2">(</span>f<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">5</td><td>   f <span class="k3">-</span><span class="k3">=</span> <span class="k2">(</span><span class="k1">float</span><span class="k2">)</span>num<span class="k2">;</span></td></tr><tr><td class="number">6</td><td>   recip <span class="k3">=</span> <span class="k2">(</span><span class="k2">(</span>f <span class="k3">!</span><span class="k3">=</span> <span class="n">0</span>.<span class="n">0f</span><span class="k2">)</span> ? <span class="k2">(</span><span class="k1">unsigned</span> <span class="k1">int</span><span class="k2">)</span><span class="k2">(</span><span class="n">1</span>.<span class="n">0</span><span class="k3">/</span>f<span class="k2">)</span><span class="k2">:</span> <span class="n">0</span><span class="k2">)</span></td></tr><tr><td class="number">7</td><td>&#160;</td></tr><tr><td class="number">8</td><td>   <a href="http://www.allegro.cc/manual/pack_iputl" target="_blank"><span class="a">pack_iputl</span></a><span class="k2">(</span>pf, num<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">9</td><td>   <a href="http://www.allegro.cc/manual/pack_iputl" target="_blank"><span class="a">pack_iputl</span></a><span class="k2">(</span>pf, recip<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">10</td><td><span class="k2">}</span></td></tr><tr><td class="number">11</td><td>&#160;</td></tr><tr><td class="number">12</td><td><span class="k1">float</span> load_float<span class="k2">(</span><a href="http://www.allegro.cc/manual/PACKFILE" target="_blank"><span class="a">PACKFILE</span></a> <span class="k3">*</span>pf<span class="k2">)</span></td></tr><tr><td class="number">13</td><td><span class="k2">{</span></td></tr><tr><td class="number">14</td><td>   <span class="k1">float</span> f <span class="k3">=</span> <span class="k2">(</span><span class="k1">float</span><span class="k2">)</span><a href="http://www.allegro.cc/manual/pack_igetl" target="_blank"><span class="a">pack_igetl</span></a><span class="k2">(</span>pf<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">15</td><td>   <span class="k1">unsigned</span> <span class="k1">int</span> recip <span class="k3">=</span> <a href="http://www.allegro.cc/manual/pack_igetl" target="_blank"><span class="a">pack_igetl</span></a><span class="k2">(</span>pf<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">16</td><td>   <span class="k1">if</span><span class="k2">(</span>recip<span class="k2">)</span></td></tr><tr><td class="number">17</td><td>      f <span class="k3">+</span><span class="k3">=</span> <span class="n">1</span>.<span class="n">0</span><span class="k3">/</span>recip<span class="k2">;</span></td></tr><tr><td class="number">18</td><td>   <span class="k1">return</span> f<span class="k2">;</span></td></tr><tr><td class="number">19</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>I can&#39;t gaurantee what kind of accurcy you&#39;ll get with that, though.</p><p>If you know the size of the float, and know that floats will be the same endianess as  integers, you can use a cast, though:
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">void</span> save_float<span class="k2">(</span><a href="http://www.allegro.cc/manual/PACKFILE" target="_blank"><span class="a">PACKFILE</span></a> <span class="k3">*</span>pf, <span class="k1">float</span> f<span class="k2">)</span>
<span class="k2">{</span>
   <a href="http://www.allegro.cc/manual/pack_iputl" target="_blank"><span class="a">pack_iputl</span></a><span class="k2">(</span>pf, <span class="k3">*</span><span class="k2">(</span>uint32_t<span class="k3">*</span><span class="k2">)</span><span class="k3">&amp;</span>f<span class="k2">)</span><span class="k2">;</span>
<span class="k2">}</span>

<span class="k1">float</span> load_float<span class="k2">(</span><a href="http://www.allegro.cc/manual/PACKFILE" target="_blank"><span class="a">PACKFILE</span></a> <span class="k3">*</span>pf<span class="k2">)</span>
<span class="k2">{</span>
   <span class="k1">int</span> num <span class="k3">=</span> <a href="http://www.allegro.cc/manual/pack_igetl" target="_blank"><span class="a">pack_igetl</span></a><span class="k2">(</span>pf<span class="k2">)</span><span class="k2">;</span>
   <span class="k1">return</span> <span class="k3">*</span><span class="k2">(</span><span class="k1">float</span><span class="k3">*</span><span class="k2">)</span><span class="k3">&amp;</span>num<span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kitty Cat)</author>
		<pubDate>Sat, 11 Feb 2006 13:34:02 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Since it&#39;s VB I can&#39;t guarantee the variable size of a single, or an int -- I got it working, and I also notice the evil accuracy.  Thank you...</p><p>1/.34 = aprox 3, 1/3 = .333-&gt;  But that&#39;s good enough.</p><p>-- Does Floor always round towards 0, or round down?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Michael Jensen)</author>
		<pubDate>Mon, 13 Feb 2006 23:27:06 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>floor clips any decimals afaik.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Jonatan Hedborg)</author>
		<pubDate>Tue, 14 Feb 2006 01:42:48 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Floor rounds always down, ceil always up. A cast rounds towards zero.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Fladimir da Gorf)</author>
		<pubDate>Tue, 14 Feb 2006 02:11:59 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Ok, so it seems like this will work with negative numbers also then -- that&#39;s good.
</p><div class="source-code snippet"><div class="inner"><pre>value <span class="k3">=</span> <span class="k3">-</span><span class="n">3</span>.<span class="n">5</span>
fval <span class="k3">=</span> <span class="k3">-</span><span class="n">4</span> <span class="k2">{</span><a href="http://www.delorie.com/djgpp/doc/libc/libc_330.html" target="_blank">floor</a><span class="k2">(</span>value<span class="k2">)</span><span class="k2">}</span>
pval <span class="k3">=</span> <span class="n">2</span>  <span class="k2">{</span><span class="n">1</span><span class="k3">/</span><span class="k2">(</span>value-fval<span class="k2">)</span><span class="k2">}</span>
<span class="c">/* ---------------------------- */</span>
output <span class="k3">=</span> <span class="k3">-</span><span class="n">3</span>.<span class="n">5</span> <span class="k2">{</span>fval <span class="k3">+</span> <span class="k2">(</span><span class="n">1</span><span class="k3">/</span>pval<span class="k2">)</span><span class="k2">}</span>
</pre></div></div><p>
Looks good.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Michael Jensen)</author>
		<pubDate>Tue, 14 Feb 2006 11:31:01 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Every computer I have ever programed on uses IEEE-754 format -- Intel, PowerPC, Motorola, SPARC, UltraSPARC.  You can just save the data in binary form.  I don&#39;t know if software emulators for ARM use IEEE-754, but I wouldn&#39;t be surprised if they did.</p><p>If you are truly concerned about being able to load it, you can write an IEEE-754 loader in portable C or you can save as text.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (gillius)</author>
		<pubDate>Wed, 15 Feb 2006 03:59:00 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>When you save as text it rounds it anyway, and the only &quot;binary&quot; save method I have from the allegro packfile routines that doesn&#39;t require the data to be a pointer is save int32, int16, and int8 (char/byte) -- I could overload the int32 method to support single (float) and just hope that the marshalling converts it, but that could have some really evil side effects...</p><p>edit:<br />I wonder if there is a text-based math library out there (I know it would be slow, but imagine the accuracy, it could be used for high-precision calculator applications) -- by text based, I mean that a given number is stored in a string &quot;4382749832432804327432.3213762173921873821739213&quot; is probably a higher precision number than most numeric types would allow for instance, but string, who cares? -- obviously all the math would have to be done in software, and it would be painfully slow compared to hardware math.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Michael Jensen)</author>
		<pubDate>Wed, 15 Feb 2006 07:16:13 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>You don&#39;t <i>have</i> to do rounding to print out a float.  The Java language I believe specifies that a float is printed to contain exactly the number of digits that it takes to completely distinguish one float from another, and no more.  In this manner, printing a float as text and reading it back in is an exact copy.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (gillius)</author>
		<pubDate>Wed, 15 Feb 2006 07:21:08 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Hmmm... I guess that makes sense -- There is probably a way in VB.NET also, probably one of the ToString() format strings... I&#39;ll have to look into that.  I guess I&#39;m just soo used to string formatters messing with my floats...
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Michael Jensen)</author>
		<pubDate>Thu, 16 Feb 2006 12:30:30 +0000</pubDate>
	</item>
</rss>
