10 cool bitwise operator hacks and tricks every programmer must know

Bitwise operators are used to manipulate data at its lowest level (bit level). Data in memory (RAM) is organized as a sequence of bytes. Each byte is a group of eight consecutive bits. We use bitwise operators whenever we need to manipulate bits directly. In this post I will show you some cool bitwise operator hacks and tricks. These hacks will boost your programming skill. Quick overview of Bitwise operators

1. Bitwise AND (&) operator compare two bits and return 1 if both bits are set (1), otherwise return 0.
2. Bitwise OR (|) operator compare two bits and return 1 if any of them or both bits are set (1), otherwise return 0.
3. Bitwise XOR (^) operator compare two bits and return 1 if either of the bits are set (1), otherwise return 0.
4. Bitwise complement (~) operator takes single operand and invert all the bits of the operand.
5. Bitwise right shift (>>) operator insert 0 bit at most significant bit and shift subsequent bits to right.
6. Bitwise Left shift (<<) operator insert 0 bit at least significant bit and shift subsequent bits to left.

Let us get started and learn some cool bitwise operator hacks and tricks.

Bitwise operator hacks and tricks

1. Right shift (>>) operator is equivalent to division by 2

Want to divide a number by 2 quicky. Here you go, use bitwise right shift operator to divide an integer by 2. Each right shift operation reduces the number (operand) to its half.

Example:

#include <stdio.h>

int main()
{
int a = 24;

// Use bitwise right shift to divide
// number by power of 2
printf("24 / (2^1) => %d\n", (a >> 1));
printf("24 / (2^2) => %d\n", (a >> 2));
printf("24 / (2^3) => %d\n", (a >> 3));

return 0;
}

Output:

24 / (2^1) => 12
24 / (2^2) => 6
24 / (2^3) => 3
2. Left shift (<<) operator is equivalent to multiplication by 2

Similar to division, you can use bitwise left shift operator to quickly multiply a number by the power of 2. Each left shift makes doubles the number (operand).

Example:

#include <stdio.h>

int main()
{
int a = 12;

// Use bitwise left shift to multiply
// number by power of 2
printf("12 * (2^1) => %d\n", (a << 1));
printf("12 * (2^2) => %d\n", (a << 2));
printf("12 * (2^3) => %d\n", (a << 3));

return 0;
}

Output:

12 * (2^1) => 24
12 * (2^2) => 48
12 * (2^3) => 96
3. Use bitwise AND (&) operator to check even or odd number

To check even or odd number we generally use modulo division operator. You can use bitwise AND & operator to check whether a number is even or odd.

You can also use this trick to check if a number is divisible by two or not.

Example:

#include <stdio.h>

int main()
{
int num1 = 10, num2 = 21;

// Check even odd
if (num1 & 1)
printf("%d is an ODD number.\n", num1);
else
printf("%d is an EVEN number.\n", num1);

if(num2 & 1)
printf("%d is an ODD number.\n", num2);
else
printf("%d is an EVEN number.\n", num2);

return 0;
}

Output:

10 is an EVEN number.
21 is an ODD number.
4. Store multiple flags in single variable

We often use variable to store boolean flag values e.g. isEven, isMarried, isPrime etc. Instead of wasting 4 byte to store single flag. You can use bit masking to store multiple flag values in single variable. A 4 byte unsigned integer can store 32 flags.

We use bitwise OR | operator to set flag. To unset or check flag status we use bitwise AND & operator. At a high level it is known as bit masking, but you can think it as set, unset and check a bit status.

Example:
In below example I will set, check and reset three flag values. Flag for marital status at 0th bit, voting status at 1st bit, VISA status at 2nd bit.

#include <stdio.h>

int main()
{
// Make all bits off.
unsigned char flag = 0;

// Set marital status YES, i.e. 0th bit 1
// (flag => 0000 0001 = 1)
flag = flag | 1;

// Set voting status YES, i.e. 1st bit 1
// (flag => 0000 0011 = 3)
flag = flag | 2;

// Set VISA eligibility status YES, i.e. 2nd bit 1
// (flag => 0000 0111 = 7)
flag = flag | 4;

// Print flag value
printf("flag, DECIMAL = %d, HEX = %x\n\n", flag, flag);

// Check if married
if(flag & 1)
printf("You are married.\n");
else
printf("You are not married.\n");

// Check voting eligibility
if(flag & 2)
printf("You are eligible for voting.\n");
else
printf("You are not eligible for voting.\n");

// Check VISA status
if(flag & 4)
printf("You are eligible to get VISA.\n");
else
printf("You are not eligible to get VISA.\n");

// Unset or set all flags to false.
flag = flag & (~(1 << 0));
flag = flag & (~(1 << 1));
flag = flag & (~(1 << 2));

// Print flag value
printf("\nflag, DECIMAL = %d, HEX = %x\n", flag, flag);

return 0;
}

Output:

flag, DECIMAL = 7, HEX = 7

You are married.
You are eligible for voting.
You are eligible to get VISA.

flag, DECIMAL = 0, HEX = 0
5. Quickly find 1s and 2s complement of a number

One's complement of a binary number is defined as value obtained after inverting all bits of the number. We use bitwise complement operator ~ operator, to find 1s complement of a number.

You can get two's complement of a binary number by adding 1 to its one's complement.

Example:

#include <stdio.h>

int main()
{
int num = 8;

// ~num yields 1s complement of num
printf("1s complement of %d = %d\n", num, (~num));

// (~num + 1) yields 2s complement of num
printf("2s complement of %d = %d\n", num, (~num + 1));

return 0;
}

Output:

1s complement of 8 = -9
2s complement of 8 = -8
6. Quickly convert character to lowercase and uppercase

This is my favourite hack. You can use bitwise OR and AND operator to convert a character to lowercase and uppercase respectively.

To convert a character ch to lowercase use ch = ch | ' '. Whether ch is uppercase or lowercase. Result of this is always a lowercase character.

To convert a character ch to uppercase use ch = ch & '_'. It always return uppercase character, doesn't matter whether ch is uppercase or lowercase.

Example:

#include <stdio.h>

int main()
{
// Convert to lowercase
printf("'a' => '%c'\n", ('a' | ' '));
printf("'A' => '%c'\n", ('A' | ' '));

// Convert to uppercase
printf("'a' => '%c'\n", ('a' & '_'));
printf("'A' => '%c'\n", ('a' & '_'));

return 0;
}

Output:

'a' => 'a'
'A' => 'a'
'a' => 'A'
'A' => 'A'
7. Quick conditional assignment hack

This is one of my favourite bitwise XOR ^ hack. In programming you may require some conditional assignment such as,

if (x == a)
x = b;
if (x == b)
x = a;

You can use bitwise XOR operator for these type of assignment.

Example:

#include <stdio.h>

int main()
{
int a = 10, b = 20, x;

// Original value
x = a;
printf("x = %d\n", x);

// if (x == a) x = b;
x = a ^ b ^ x;
printf("x = %d\n", x);

// if (x == b) x = a;
x = a ^ b ^ x;
printf("x = %d\n", x);

// x = 0
x = x ^ x;
printf("x = %d\n", x);

return 0;
}

Output:

x = 10
x = 20
x = 10
x = 0
8. Find maximum or minimum without if...else

Another hack frequently asked in interviews. We all know to find maximum or minimum using if else. Let's do it bitwise way.

Example:

#include <stdio.h>

int main()
{
int x = 10, y = 20;

int min = (y ^ (x ^ y) & -(x < y));
int max = (x ^ (x ^ y) & -(x < y));

printf("Minimum(10, 20) => %d\n", min);
printf("Maximum(10, 20) => %d\n", max);

return 0;
}

Output:

Maximum(10, 20) => 20
Minimum(10, 20) => 10
9. Use bitwise XOR (^) operator to quickly swap two number without third variable

Frequently asked in interviews, how to swap two numbers without using third variable. You can use bitwise XOR ^ operator to swap two variables without using third variable.

Example:

#include <stdio.h>

int main()
{
int a, b;

// Input two numbers
printf("Enter two numbers to swap: ");
scanf("%d%d", &a, &b);

// Print original values.
printf("Original value: a=%d, b=%d\n", a, b);

// Swap a with b
a ^= b;
b ^= a;
a ^= b;

// Swapped values.
printf("Swapped value: a=%d, b=%d\n", a, b);

return 0;
}

Output:

Enter two numbers to swap: 10 20
Original value: a=10, b=20
Swapped value: a=20, b=10
10. Use bitwise XOR (^) operator for basic encryption and decryption

Bitwise XOR operator is one of the magical operators in C. It has a special property, suppose a and b two integers and c = a ^ b. Then, the result of a ^ b i.e. c, when XORed with a return b and vice versa.

For example:

int a, b, c;
a = 10, b=20;

c = a ^ b; // c = 30
printf("%d", (c ^ a)); // 20
printf("%d", (c ^ b)); // 10

We can use this feature of XOR operator for basic encryption/decryption.

Example:

#include <stdio.h>

#define KEY 22

int main()
{
char text;
int i;

// Input text
printf("Enter text to encrypt: ");
fgets(text, 100, stdin);

// Encrypt text
for (i=0; text[i] != '\0'; i++)
{
text[i] = text[i] ^ KEY;
}

printf("Encrypted text: %s\n", text);

// Decrypt text
for (i = 0; text[i] != '\0'; i++)
{
text[i] = text[i] ^ KEY;
}

printf("Original text: %s\n", text);

return 0;
}

Output:

Enter text to encrypt: I love C programming.
Encrypted text: _6zy`s6U6fdyqdw{{xq8
Original text: I love C programming.

Tell us your favorite bitwise operator hacks and tricks in the comments section. Or you got some more hacks please share with us.

Happy coding 😉

References: 