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. More info here – Bit-level operations – check integer is even or odd

## 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.