How to check the integer is even or odd in C/C++?

I assume, that you know what even and odd numbers are from a math perspective. However, I will refresh this knowledge just in a single sentence for a buddies who overslept that math lesson.

An even number is an integer that is exactly divisible by 2 while odd number is any integer (not a fraction) that cannot be divided exactly by 2. 

To the point! There are two common ways to check whether an integer is even or odd. Both are good and both have some unique advantages.

1. Using modulo operation

if ((n % 2) == 0)
{
// even
}
else
{
// odd
}

The advantage of using modulo % operation is that we can operate on negative integers as well as on positive what is impossible in case of bitwise operation.

2. Using bitwise operation

if ((n & 1) == 0)
{
// even
}
else
{
// odd
}

The advantages of bitwise operation & appears when we use small MCUs/microcontrollers. Time of code execution (number of required CPU cycles) and resources consumption migth be significantly smaller in compare to modulo operation case.

Some Final Words

There are many battles that you can find in the internet regarding which solution is fastest. The truth is that in most cases both are equally fast. Modern compilers optimize the operation (mod 2) to bitwise operation (and). It’s easy to check. Look at the two main functions bellow. After disassembling two binaries code will look exactly the same.

Example of using modulo operation

int main(void)
{
int n = 2022;
if ((n % 2) == 0)
{
return (1);
}
return (0)
}

Example of using bitwise operation

int main(void)
{
int n = 2022;
if ((n & 1) == 0)
{
return (1);
}
return (0)
}

Result

$ gcc main.c
$ gdb -batch -ex 'file ./a.out' -ex 'disassemble main'
Dump of assembler code for function main:
0x00000000000005d5 <+0>: push %rbp
0x00000000000005d6 <+1>: mov %rsp,%rbp
0x00000000000005d9 <+4>: movl $0x7e6,-0x4(%rbp)
0x00000000000005e0 <+11>: mov -0x4(%rbp),%eax
0x00000000000005e3 <+14>: and $0x1,%eax
0x00000000000005e6 <+17>: test %eax,%eax
0x00000000000005e8 <+19>: jne 0x5f1 <main+28>
0x00000000000005ea <+21>: mov $0x1,%eax
0x00000000000005ef <+26>: jmp 0x5f6 <main+33>
0x00000000000005f1 <+28>: mov $0x0,%eax
0x00000000000005f6 <+33>: pop %rbp
0x00000000000005f7 <+34>: retq
End of assembler dump.

Leave a Comment