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

The binary storage of floating point numbers

Floating point numbers are positive or negative numbers with a decimal fraction: numbers such as 1.0 or 17.11 or –3.12 are all floating point numbers.
On the Arduino and other microprocessors are stored in ‘floats’.
Whereas the concept of a byte or an integer is quite straightforward, a float in binary form is a bit more challenging.
A byte is simple, it is just 2⁷+2⁶+2⁵+2⁴+2³ + 2²+2¹ +2⁰.

An integer is similar, be it that it extends to 215.

But how do you store a number like –1.5 ?

Well, floats are stored on the concept that practically every number can be expressed as the multiplication of a power of 2 times  a number between 1 and 2. Take for instance 7, or 7.00 for that matter, that can be expressed as 4 * 1.75 (or 2² * 1.75).

the number  -1.5 is in fact 1 * 1.5 which is 2⁰ * 1.5, preceded by a ‘-‘ sign.
The same goes for higher numbers, say 20.5= 16 * 1.28125  (=2⁴ * 1.28125).
Sure 20.5 can also be expressed by 2*10.25, but the last number must be between 1 and 2.

So in fact every number can be represented by:
sign * 2x  * y  (y being a number between 1 and 2).

According to agreement we call ‘x’ the ‘exponent’ and ‘y’  the ‘mantissa’ though the word mantissa is also used for the fractional part of a logarithm. The IEEE standard for floating point numbers therefore encourages to use the word ‘fraction’  instead of ‘mantissa’, so we can write the above as:
floating point number= sign * 2exponent * fraction

Lets get back to the  fraction part of the number 20.5 which is 1.28125 (remember? 20.5=2⁴ * 1.28125). If we look at that a bit deeper, we can see that that is actually 1+ 1/4 + 1/32. That makes sense coz 16* (1+1/4+1/32)= 16+4+0.5=20.5.
If we would break this down again we can see that  the ‘fraction’ or mantissa is actually a sum of  fractions that all are  again 1/(a power of 2). It is probably clear by now that for 20.5 that would be 1/2⁰ + 1/2² +1/2⁵

Anyway, back to the binary storage.
As said, on the Arduino and many other processors, the floating number is stored in 32 bits and the protocol to store that follows from the notation we have learned above.
The most left bit, bit 32, stores the ‘sign’ if it is a ‘1’  the number is negative, if it is  a ‘0’ it is positive.
The next 8 bits, bits 31-24 store the exponent. as we want  values between 2128  and 2-127, we store 2¹ as 10000000 (decimal 128), 2² as 10000001 (decimal 129), 2³ as  10000010 (decimal 130)  etc… The exponent thus follows from subtracting 127 from the decimal number that is stored in bits 31-24.

The fraction or mantissa is stored in bits 23-1. However, since we know that the fraction is always between 1 an 2, we do not store  the ‘1’ as we know it is always there. We refer to that as the ‘hidden’ bit, although it is not  hidden, it is just not stored. We use bits 23-1 to indicate a sum of  the fractions 1/2, 1/4, 1/8, 1/16 etc.
So, the binary storage of a float is as follows:

sign exponent hidden fraction
20.5 0 10000011 01001000000000000000000
+ 4(131-127) 1+ 1/4 +1/32
-7 1 10000001 11000000000000000000000
2(129-127) 1+ 1/2+1/4