<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ruminant Nation &#187; PHP</title>
	<atom:link href="http://www.pupation.com/blog/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.pupation.com/blog</link>
	<description>Slipping down the throat like the little Lord Jesus dressed in velvet pantaloons.</description>
	<lastBuildDate>Sun, 17 Jan 2010 23:19:28 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>The Perils of Foreach</title>
		<link>http://www.pupation.com/blog/2010/01/the-perils-of-foreach/</link>
		<comments>http://www.pupation.com/blog/2010/01/the-perils-of-foreach/#comments</comments>
		<pubDate>Sun, 17 Jan 2010 23:17:16 +0000</pubDate>
		<dc:creator>Tonsil</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.pupation.com/blog/?p=28</guid>
		<description><![CDATA[<p><h3>The Perils of Foreach, or &#8220;I&#8217;ve got yer references dangling right here!&#8221;</h3></p>

<p>Here&#8217;s another one of those pitfalls in PHP that might be classified as a neophyte mistake, but nevertheless it bit me in the ass a while ago. I was perplexed at first why this one test I had written kept failing, and finally it boiled down to the way I was iterating through an array multiple times in the same block of code. As it turned out, I had made the mistake of leaving a reference to a variable hanging around after I was done with it. Later, in ...<p><strong>Read full post</strong>: <a href="http://www.pupation.com/blog/2010/01/the-perils-of-foreach/">The Perils of Foreach</a></p>]]></description>
			<content:encoded><![CDATA[<p><h3>The Perils of Foreach, or &#8220;I&#8217;ve got yer references dangling right here!&#8221;</h3></p>

<p>Here&#8217;s another one of those pitfalls in PHP that might be classified as a neophyte mistake, but nevertheless it bit me in the ass a while ago. I was perplexed at first why this one test I had written kept failing, and finally it boiled down to the way I was iterating through an array multiple times in the same block of code. As it turned out, I had made the mistake of leaving a reference to a variable hanging around after I was done with it. Later, in the same (unfortunately lengthy) block of code, I reused the variable name containing the reference for something else (assigned it a value), and it gave me some, shall we say, unexpected results.</p>

<p>Here, it&#8217;s easier to demonstrate with a short example. My bug was buried deep in some more convoluted code, this is just a simplified version of the same sort of thing:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #000088;">$fruits</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
	<span style="color: #0000ff;">'apple'</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'banana'</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'cherry'</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;foreach with assign by reference:<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fruits</span> <span style="color: #b1b100;">as</span> <span style="color: #339933;">&amp;</span><span style="color: #000088;">$fruit</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$fruit</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>foreach with assign by value:<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fruits</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$fruit</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$fruit</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>




<p>The output for this looks something like this:</p>
<code  class="terminal">foreach with assign by reference:
apple
banana
cherry

foreach with assign by value:
apple
banana
banana</code>

<p>So yeah, you&#8217;ve got your fruits in alphabetical order, and the second time you go through the list you end up with two bananas and no cherries. The hell? </p>

</p>Well, I&#8217;ve seen an example like this one at various paces on the &#8216;net, usually from some poor confused soul trying to understand where the cherry went. Sometimes you even find a quick response that says how to fix the problem. I haven&#8217;t come across an examinantion of what&#8217;s really going on, though, so I figured I&#8217;d give it a whirl. </p>

<h4>Problem Number A: Dangling Reference</h4>

<p>Let me just start by saying the example above is a very simplified example of the core problem. I&#8217;m sure some of you are wondering why I might bother writing code that uses references like this, but rather than dive into that right now, just know that I&#8217;m not insane and I had my reasons. Accepting the code as it stands, the first foreach loop is iterating through the <code >$fruits</code> array and assigning individual elements by <strong>reference</strong>. It works well enough &#8211; if you only ran that part of the program, you would never see a bug. However, there is a problem with it, and it is this: the <code >$fruit</code> reference remains even after the foreach loop is over. The variable <code >$fruit</code> points to a location that contains the value &#8216;cherry&#8217;. Also, because of the way references work, the third element of the <code >$fruits</code> array <strong>also</strong> points to the value &#8216;cherry&#8217;. Check it out:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #000088;">$fruits</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
	<span style="color: #0000ff;">'apple'</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'banana'</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'cherry'</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;foreach with assign by reference:<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fruits</span> <span style="color: #b1b100;">as</span> <span style="color: #339933;">&amp;</span><span style="color: #000088;">$fruit</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$fruit</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fruits</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$fruit</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'date'</span><span style="color: #339933;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fruits</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>




<code  class="terminal">foreach with assign by reference:
apple
banana
cherry
array(3) {
  [0]=&gt;
  string(5) "apple"
  [1]=&gt;
  string(6) "banana"
  [2]=&gt;
  &amp;string(6) "cherry"
}
array(3) {
  [0]=&gt;
  string(5) "apple"
  [1]=&gt;
  string(6) "banana"
  [2]=&gt;
  &amp;string(4) "date"
}</code>

<p>As you can see, the variable <code >$fruit</code> contains a reference, even after we&#8217;re done with it in the foreach loop. It points (or &#8216;refers&#8217;, if you like) back to a memory location that happens(just after the end of the loop) to contain the string &#8216;cherry&#8217;. Look closer, though &#8211; there&#8217;s something else going on that&#8217;s equally improtant. Notice the value of <code >$fruits[2]</code>. It, too, is a reference! That&#8217;s just the way references work &#8211; the moment you create a reference to a value, the original variable that contained the value <b>also</b> becomes a reference to that value. It&#8217;s one location in memory with two pointers; assign a new value to either and the other will point to the changed value as well.</p>

<p>Now, just to completely beat this dead horse, after the foreach loop, <code >$fruit</code> contains a reference, because that&#8217;s the last thing we assigned to it. PHP doesn&#8217;t care that the loop is over, it has no way of knowing whether or not you intend to use that reference value later on. When you assign the value &#8216;date&#8217; to the variable <code >$fruit</code>, you&#8217;re putting the value &#8216;date&#8217; into the location <code >$fruit</code> was referencing. The <code >$fruits</code> array is modified, &#8216;cherry&#8217; becomes &#8216;date&#8217;.</p>

<p>Going back to the original example, it should now be (hopefully) apparent what&#8217;s going on &#8211; it&#8217;s really the same exact thing. Once the foreach by reference loop is over, <code >$fruit</code> contains a reference to a memory location that contains the string &#8216;cherry&#8217;. At the same time, <code >$fruits[2]</code> contains a reference to the same space. When we hit the second foreach loop, we&#8217;re iterating through the <code >$fruits</code> array and assiging that value to the location to which $fruit points, which (again) affects <code >$fruits[2]</code>. The 1st iteration, &#8216;apple&#8217; is assigned. On the 2nd, it&#8217;s &#8216;banana&#8217;. At this point, <code >$fruits[2]</code> and <code >$fruit</code> both point to a location containing the string &#8216;banana&#8217;. On the last iteration, <code >$fruits</code> is assigned the value of whatever value is pointed to by <code >$fruits[2]</code> which was just changed to &#8216;banana&#8217;. Here&#8217;s a modified version of the original example with some different output:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #000088;">$fruits</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
	<span style="color: #0000ff;">'apple'</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'banana'</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'cherry'</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;foreach with assign by reference:<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fruits</span> <span style="color: #b1b100;">as</span> <span style="color: #339933;">&amp;</span><span style="color: #000088;">$fruit</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$fruit</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>foreach with assign by value:<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$count</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fruits</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$fruit</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;assigning value of <span style="color: #000099; font-weight: bold;">\$</span>fruits[<span style="color: #006699; font-weight: bold;">$count</span>] to <span style="color: #000099; font-weight: bold;">\$</span>fruit &quot;</span> <span style="color: #339933;">.</span>
	     <span style="color: #0000ff;">&quot;and also <span style="color: #000099; font-weight: bold;">\$</span>fruits[2]: &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$fruits</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$count</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$count</span><span style="color: #339933;">++;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;after 2nd foreach loop:<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fruits</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>




<code  class='terminal'>foreach with assign by reference:
apple
banana
cherry

foreach with assign by value:
assigning value of $fruits[0] to $fruit and also $fruits[2]: apple
assigning value of $fruits[1] to $fruit and also $fruits[2]: banana
assigning value of $fruits[2] to $fruit and also $fruits[2]: banana
after 2nd foreach loop:
array(3) {
  [0]=&gt;
  string(5) "apple"
  [1]=&gt;
  string(6) "banana"
  [2]=&gt;
  &amp;string(6) "banana"
}</code>

<h4>Finally, a Point</h4>

<p>If you&#8217;ve managed to get this far, congratulations! The upshot of all this dancing around with references is this little nugget o&#8217; advice:</p>
<h5>Always unset a reference variable after you&#8217;re done with it, especially following a foreach loop!!!</h5>
<p>If you don&#8217;t believe me, check out the <a href="http://us3.php.net/manual/en/control-structures.foreach.php">php documentation</a>. Doing so will destroy the reference, and prevent the kind of bug that can be quite the PITA to pin down. Here, then, is the example one last time, this time &#8220;fixed&#8221; with an unset call:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #000088;">$fruits</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
	<span style="color: #0000ff;">'apple'</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'banana'</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'cherry'</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;foreach with assign by reference:<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fruits</span> <span style="color: #b1b100;">as</span> <span style="color: #339933;">&amp;</span><span style="color: #000088;">$fruit</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// etc.</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fruit</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fruits</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$fruit</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// etc.</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;after 2nd foreach loop:<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fruits</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>




<p>And the blessed, correct output:</p>
<code  class='terminal'>foreach with assign by reference:
after 2nd foreach loop:
array(3) {
  [0]=&gt;
  string(5) "apple"
  [1]=&gt;
  string(6) "banana"
  [2]=&gt;
  string(6) "cherry"
}</code>
]]></content:encoded>
			<wfw:commentRss>http://www.pupation.com/blog/2010/01/the-perils-of-foreach/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Trouble With Floats, and not the Root Beer Kind</title>
		<link>http://www.pupation.com/blog/2009/11/the-trouble-with-floats-and-not-the-root-beer-kind/</link>
		<comments>http://www.pupation.com/blog/2009/11/the-trouble-with-floats-and-not-the-root-beer-kind/#comments</comments>
		<pubDate>Sun, 15 Nov 2009 20:12:18 +0000</pubDate>
		<dc:creator>Tonsil</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://192.168.1.102/blog/?p=15</guid>
		<description><![CDATA[<p>This post is about float values, some basic computer science, and the PHP-specific handling of floats. It&#8217;s geared for the beginner, but please read on even if you feel you&#8217;re above it, as I tried to include some interesting bits at the end.</p>
<p>As a programmer, I have read through more fat books than I care to think about. That doesn&#8217;t mean I&#8217;ve retained it &#8211; quite the opposite. I&#8217;ve probably forgotten at least ten facts for any one I remember. That said, there are times when I&#8217;m working on something that I have that &#8220;Oh yeahhhh&#8230; a-Dur! *self thwap*&#8221; moment ...<p><strong>Read full post</strong>: <a href="http://www.pupation.com/blog/2009/11/the-trouble-with-floats-and-not-the-root-beer-kind/">The Trouble With Floats, and not the Root Beer Kind</a></p>]]></description>
			<content:encoded><![CDATA[<p>This post is about float values, some basic computer science, and the PHP-specific handling of floats. It&#8217;s geared for the beginner, but please read on even if you feel you&#8217;re above it, as I tried to include some interesting bits at the end.</p>
<p>As a programmer, I have read through more fat books than I care to think about. That doesn&#8217;t mean I&#8217;ve retained it &#8211; quite the opposite. I&#8217;ve probably forgotten at least ten facts for any one I remember. That said, there are times when I&#8217;m working on something that I have that &#8220;Oh yeahhhh&#8230; a-Dur! *self thwap*&#8221; moment when something I should know pops up and says hello. Recently, I had a moment like that when I was (foolishly) trying to check a float value for equality in PHP.</p>
<p>Allow me to back the truck up for a moment. In case you don&#8217;t know, float values are numbers with a decimal component, e.g. 1.234 . In PHP, you end up with a float any time you explicitly create a decimal, like so:</p>

<code >$x = 2.234;</code>

Or, for example, if you divide two integers, like this:</p>

<code >$x = 2 / 3;</code>

<p>You can end up with a float value many other ways, but you get the idea. The trouble with floats is this: the value of a float is <strong>always</strong> an estimate!. That might not seem like a surprise to you when considering the decimal representation of, say, 2/3. However, it can be annoying if you (as I did) stop thinking of floats as what they are for a moment in the context of what you&#8217;re doing.</p>

<p>Before I babble any further, here&#8217;s a stripped down code example, illustrating the basic problem I encountered:


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #000088;">$x</span> <span style="color: #339933;">=</span> <span style="color:#800080;">.6</span> <span style="color: #339933;">+</span> <span style="color:#800080;">.3</span> <span style="color: #339933;">+</span> <span style="color:#800080;">.1</span><span style="color: #339933;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$x</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// value of $x shows as &quot;float(1)&quot;</span>
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$x</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$x</span> = 1. All is right in the world<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$x</span> != 1? The hell you say?!?<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>




At this point, beginners might be wondering what&#8217;s going on, while experienced programmers might wonder what I was thinking. I&#8217;ll explain the scenario in a bit, but the short version is that I was working with percentage values that I expected, under normal conditions, to add up to 100%. But first, let&#8217;s clear up the apparent weirdness in the script above. Remember when I said the float values are estimates? That&#8217;s what&#8217;s going on here. Even though to us, .6 + .3 + .1 is clearly 1, the computer has to do some rounding.</p>

<p>Computers don&#8217;t store numbers using base 10. That is, a computer doesn&#8217;t think of .6 as six tenths. It tries to store that fraction as best it can using what essentially boils down to ones and zeroes. In that conversion, rounding occurs. It is similar to when we have to represent a fraction like 2/3 as a decimal. Without &#8220;cheating&#8221; and putting a line over the repeating digit, the best we can do is something like 0.66666667, where the final 7 is the point at which we got tired of writing sixes, gave up, and wrote a 7. We round up, figure that&#8217;s close enough, and move on with our lives. The computer does the same thing, but some times it&#8217;s not as obvious.</p>

<p>In the above script, when the value of $x is dumped to the screen, it is shown as &#8220;float(1)&#8221;. That really only adds to the confusion, because it&#8217;s clearly <strong>not</strong> equal to 1. So what is $x? The <a href="http://us3.php.net/var_dump" target="_new">var_dump</a> function is actually rounding off the value. However, in PHP, you can output the value of a float with forced precision using the <a href="http://us3.php.net/printf" target="_new">printf</a> function, using some formatting directives. Here&#8217;s an example:

<code >printf("%.30f", $x);</code>

The string &#8220;%.30f&#8221; is what&#8217;s called a *conversion specifier* that tells the computer to represent the argument (the $x) as a float with a precision of 30 decimal places. See <a href="http://www.php.net/manual/en/function.sprintf.php" target="_new">the documentation</a> for more information. When we add that to the example script and run it, things become a little easier to understand:


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #000088;">$x</span> <span style="color: #339933;">=</span> <span style="color:#800080;">.6</span> <span style="color: #339933;">+</span> <span style="color:#800080;">.3</span> <span style="color: #339933;">+</span> <span style="color:#800080;">.1</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;var_dump of <span style="color: #000099; font-weight: bold;">\$</span>x: <span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$x</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// value of $x shows as &quot;float(1)&quot;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span> more precise version of <span style="color: #000099; font-weight: bold;">\$</span>x:&quot;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;<span style="color: #009933; font-weight: bold;">%.30f</span><span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$x</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// value of $x shows as 0.999999999999999822364316059975</span>
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$x</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$x</span> = 1. All is right in the world<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$x</span> != 1? The hell you say?!?<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>




Ahh &#8211; there it is. The value of $x, though close to 1, is really 0.999999999999999822364316059975&#8230; as far as the computer is concerned. So even though 60% + 30% + 10% should add up to 100% in our book, the computer may not agree. The question is, how do we make the computer agree? The answer: the same way we got into this mess in the first place &#8211; by rounding. PHP&#8217;s <a href="http://us3.php.net/round">round()</a> function allows a second optional parameter for precision, indication the number of zeroes after the decimal that we actually care about. In this example, 5 ought to be sufficient. What we can do is round the value we&#8217;re testing for a certain precision before the comparison. We&#8217;re effectively saying, &#8220;Is this number near enough to one as makes no difference?&#8221;.</p>

<p>Here&#8217;s the final revised code:


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #000088;">$x</span> <span style="color: #339933;">=</span> <span style="color:#800080;">.6</span> <span style="color: #339933;">+</span> <span style="color:#800080;">.3</span> <span style="color: #339933;">+</span> <span style="color:#800080;">.1</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;var_dump of <span style="color: #000099; font-weight: bold;">\$</span>x: <span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$x</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// value of $x shows as &quot;float(1)&quot;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span> more precise version of <span style="color: #000099; font-weight: bold;">\$</span>x:<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;<span style="color: #009933; font-weight: bold;">%.30f</span><span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$x</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// value of $x shows as 0.999999999999999822364316059975</span>
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">round</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$x</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">5</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$x</span> = 1. All is right in the world<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$x</span> != 1? The hell you say?!?<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>




Finally, 1 is equal to 1 again, and all is right in the world. We can breathe a sigh of relief, and get back to more important things, like listening to <a href="http://www.newmodelarmy.org/" target="_new">New Model Army</a>.</p>

<p>That does it for the basic bit, and ends the &#8220;beginner&#8221; part of this post. For the truly masochistic: Here&#8217;s a description of the scenario:</p>

<p>I was working on something that involved percentage weights for a list of values. Basically, each value had a weight reflecting its relevance that was factored in when all of the values were added. The sum of the weights was 100%, and were 60%, 30%, and 10% for the 3 values. In essence, here&#8217;s how it played out:</p>

<code >$adjusted_value = $value1 * .6 + $value2 * .3 + $value3 * .1;</code>

<p>So far so good. However, I also needed to account for the possibility that all three values might not be present. For the requirements of the problem (and I&#8217;m keeping the example much more simplified than the actual code involved), I needed to &#8217;scale&#8217; the adjusted_value by the total weights of the values that were present. For example, if only the first two values were present, the total weight would be 60% + 30% = 90%, so I would have to divide my adjusted_value by the total weight, or:</p>

<code >$total_weight = .6 + .3;
$adjusted_value = $adjusted_value / $total_weight;
</code>

</p>In the code, I had a check for each value being included, and if it existed (was not null), added the weight to the $total_weight. At this point, everything was groovy. The problem I encountered was when I was checking the value of the $total_weight, and firing code based on whether or not it totaled 100%. What I wanted the code to do at that point is immaterial to the bug, what&#8217;s important is that the code was never being fired. Here&#8217;s a stripped down version of the code:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$weights</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color:#800080;">.6</span><span style="color: #339933;">,</span> <span style="color:#800080;">.3</span><span style="color: #339933;">,</span> <span style="color:#800080;">.1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$values</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">75</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">62</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">80</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$count</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$total_weight</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$adjusted_value</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$v</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$v</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$adjusted_value</span> <span style="color: #339933;">+=</span> <span style="color: #000088;">$v</span> <span style="color: #339933;">*</span> <span style="color: #000088;">$weights</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$count</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$total_weight</span> <span style="color: #339933;">+=</span> <span style="color: #000088;">$weights</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$count</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000088;">$count</span><span style="color: #339933;">++;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$total_weight</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #666666; font-style: italic;">// covers case to avoid divide by zero</span>
  <span style="color: #000088;">$adjusted_value</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">elseif</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$total_weight</span> <span style="color: #339933;">!=</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #666666; font-style: italic;">// error: this *always* gets fired!</span>
  <span style="color: #000088;">$adjusted_value</span> <span style="color: #339933;">/=</span> <span style="color: #000088;">$total_weight</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #666666; font-style: italic;">// code that never gets fired, even at 100%</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>




The problem line, as should be obvious is this:

<code >} elseif($total_weight != 1) { </code>

<p>Changing the comparison to round the float value being compared gives me the result I expected:

<code >} elseif(round($total_weight, 5) != 1) { </code>

Once again, all is right in the world.</p>]]></content:encoded>
			<wfw:commentRss>http://www.pupation.com/blog/2009/11/the-trouble-with-floats-and-not-the-root-beer-kind/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
