Checking for odd and even numbers on the Arduino

Trying to determine if a number is odd or even on an Arduino is rather simple. There are several ways, but the easiest ways are to either take the modulo of the number to be tested, or do a bitwise AND on the Least Significant Bit.
If x % 2 is ‘0’ that means that x is even. If it not zero, it is an uneven number.
Similar for the bitwise test
If x & 1 is ‘1’ it must be an odd number. If it is ‘0’ it must be an even number.

If you want a specific action in your program to happen every so many hours or say just on the odd or even hours, that is rather simple.

Suppose I have a hydroponics system that I want to irrigate 6 times a day.
I have an Arduino +RTC and  the hours are stored in variable ‘hour’.

6 times a day is  every  4 hours.
I could of course specify the action 6 times, but there is  a simpler way: I can just check if the hour can be divided by 4. How do I do that? Well, a number  can be divided by 4 if it can be divided  by two, and then still would be even. (ofcourse you could check for x%4==0 but this is just to illustrate).
So I would have the condition:

if(((hour / 2) & 1) == 0) 
  {
   // then it must be 0,4,8,12,16,20 hr
  }

Because:
0/2=0  0&1=0
4/2=2  2&1=0
etc…

Sadly of course that may work on paper arithmetic, but it doesn’t work on a microcontroller like the Arduino, for the simple reason that bytes and integers don’t know fractions. So if ‘hour’ would be ‘3’,  ‘hour/2’ would not be 1.5 but 1. Well, no problem there, but if it would be ‘5’, hour / 2 would not be 2.5 but ‘2’. That is still an even number and that would make the computer think ‘5’ is in fact even.

This is what numbers 0-23 in bytes or integers look like when divided by 2

0=>  0 – Computer thinks its dividable by 4
1=>  0 – Computer thinks its dividable by 4  and is wrong
2=>  1
3=>  1
4=>  2 – Computer thinks its dividable by 4
5=>  2 – Computer thinks its dividable by 4 and is wrong
6=>  3
7=>  3
8=>  4 – Computer thinks its dividable by 4
9=>  4 – Computer thinks its dividable by 4 and is wrong
10=> 5
11=> 5
12=> 6 – Computer thinks its dividable by 4
13=> 6 – Computer thinks its dividable by 4 and is wrong
14=> 7
15=> 7
16=> 8 – Computer thinks its dividable by 4
17=> 8 – Computer thinks its dividable by 4 and is wrong
18=> 9
19=> 9
20=> 10 – Computer thinks its dividable by 4
21=> 10 – Computer thinks its dividable by 4 and is wrong
22=> 11
23=> 11

So instead of 6 actions, I get 12 actions.
There are several solutions for this. One solution could be to use floats, but they consume 4 bytes, where we prior could use 1 byte  for the hour. Also, as they are stored differently, the ‘& 1’ would give unpredictable results and the modulo function also doesn’t work on floats. So that would probably create more problems than it would solve.
The better solutions becomes immediately clear from the the table: if we first filter out the odd numbers, then divide by 2 and then check if the number is still even, then we have obtained our goal.

Condition becomes:

if ((hour & 1) == 0)  // filter out/discard odd numbers
   {
     if(((hour / 2) & 1) == 0)  // divide by two and check for LSB
       {
        //then it must be 0,4,8,12,16,20 hr
        //take action
       }
   }

The ‘x & 1’ method works for the standard arduino negative integers as well. Try:

void setup()
{
	Serial.begin(9600);
	Serial.println
	("Begin");
	for (int x = -10; x < 10; x++)
	{
		Serial.print(x);

		if((x & 1) == 0)

			Serial.print(" Even");
		else
		{
			Serial.print(" odd");
		}
		Serial.println();
	}
}

void loop()
{
}

it will not work on floats

However, as said a much quicker way would be: if(x % 4==0), but this is just to clear the principle

 

Advertisements

4 thoughts on “Checking for odd and even numbers on the Arduino

  1. Allow me to be a smart-ass please. Bitwise operations are much faster than things like dividing. As long as your “every y” uses an y that is a power of 2, the fastest metod would be if (x & z == 0) {…} where z is a constant that equals 2^y minus 1. So for the 4 hour example: if (x&3 == 0) {…}. Another advatage is that if you’d want to do something like every 4 hours, but starting at hour 1 (so 1, 5, 9 etc), you’s simply use if (x&3 == 1) {…}.

    Optimizing code in a resource-scarce environment is FUN! 🙂

    1. That is true and actually I have used them in my own code as well. But many people hav problems getting their head around bitwise operations so I didnt go deeper than using the ‘&’, keeping the divide to keep it simple.
      Where I explain the ‘every so many hours’, which could also be done by a modulo function the divides already give considerable memory gain compared to the modulo(%).
      When using attiny’s sometimes the ‘easy way’is too memory greedy.I think one time when I used the ‘map’ function it used half the memory of my attiny whereas just a division by 4 is a few bytes and a bitwise oepration might shave off a few more bytes.
      I agree it is fun to optimize code coz memory is tight.

      BTW, smart assing is always appreciated here

      1. Simple (for our brains): Yup, but I know you are anal about using the absolute lowest spec chips!

        That last remark: I will keep that in mind 😉

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s