Are You Odd?

Occasionally the needs arises to determine if a number is odd or even. Why would you need to do this? One example is the 'striping' of output, where information is presented in rows, and alternating rows have a different background color, like this:

Row1
Row2
Row3



You would think that languages would all have a function for this by now, but just as determining whether a year is a leap year is often still up to the programmer, so too is whether a number is odd or even.

Here are two PHP methods for making the determination. No doubt there are more, but one of these should meet you need.

Method 1 - Using modulo arithmetic


<pre>$isEven = ($value%2==0);</pre>

Method 2 - Using bit operation


<pre>$isEven = (($value & ($value -1)) == 0);</pre>

In Method 1, we're computing the value mod(ulo) 2. Modulo math is simply dividing the value by the modulo value, with the remainder being the result. So 6 modulo 5, which is written 11%5 in PHP, would be the same as dividing 5 into 11, which goes in twice with a remainder of one, and so 1 is the result. With mod 2, if the remainder is 0, the value was divided evenly by 2 , which means that the value is even.

In Method 2, we're performing a bit AND operation on the original value. We're subtracting 1 from the value, and then AND'ing the bits.

The AND operation compares positional bits in two values. Remember that bits begin on the right, and each is a power of 2. If the status of both bits (on=1, off=0) in any position is on, then that bit is turned on in the result. Let's look at two examples.


<pre>
VALUE BITS
3 2 1 (Bit Position)
4 2 1 (Bit Value)

4 1 0 0
3 0 1 1

0 0 0 0
</pre>

In this example, none of the bit comparions yield matching conditions. We're comparing 1-0, 0-1, 0-1, and the result of each comparison is 0 (false). This gives us a result of 000, which is 0. In this method, 0 means an even number, which is what 4 is. Let's look at the second example.


<pre>
VALUE BITS
3 2 1 (Bit Position)
4 2 1 (Bit Value)

5 101
4 100

4 100
</pre>

In this example we are comparing 5 and (5-1). With bit 1, the two conditions are different, so the result's bit 1 is left off. Bit 2 in both numbers is off, so bit 2 in the result is left off. Bit 3, however, is on in both numbers, so bit 3 in the result is turned on, which gives the result a value of 4. Since the result is not 0, the original value, which was 5, is odd.

Given these two methods, let's construct a function for performing the check. The way the following function is used will depend on what result you need when the value is even or odd. You may want the words 'odd' or 'even' returned, and we'll see an example using that in a moment. Alternatively, you may want true if even and false if odd. This function is written to default to returning 2 for even, 1 for odd, and 0 for an error, but you can pass parameters to change the returns to whatever you need. The function can be used with either method, simply replace the /* insert method here */ with either ($value%2==0) or (($value & ($value -1)) == 0).


<pre>
function odd_even($value=0,$even=2,$odd=1,$error=false) {

/***
* (c)2009 Ayen Designs - license is granted for unlimited use
* This function determines whether a value is odd or even
* INPUT $value - a non-zero value
* RETURN $odd if odd
* $even if even
* $error if the value is 0 or non-numeric or $odd=$even
*/
// check for error conditions

if ($value==0 || !is_numeric($value) || $even==$odd) return $error;

// make the determination

return ($value%2==0)?$even:$odd;
}
</pre>

Finally, let's put the function to use. The following code will assign a class of 'odd' or 'even' to row output, thus allowing you to 'stripe' the output.


<pre>
<style>
.odd {background-color: #cacaca}
.even {background-color: #fff}
</style>

$myarray = array('Line 1','Line 2','Line 3','Line 4');
echo '<table>';
foreach($myarray as $key=$row) {
echo '<tr class="' . odd_even($key,'even','odd') . '">';
echo "<td>$row>/td>";
}
echo '</table>';
</pre>

Line 1
Line 2
Line 3
Line 4

Add new comment

Markdown

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd>
  • Missing filter. All text is removed