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

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!🙂

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

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😉

😉

yes to an extend that it could be considered unhealthy