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
- Bitwise AND (
&
) operator compare two bits and return 1 if both bits are set (1), otherwise return 0. - Bitwise OR (
|
) operator compare two bits and return 1 if any of them or both bits are set (1), otherwise return 0. - Bitwise XOR (
^
) operator compare two bits and return 1 if either of the bits are set (1), otherwise return 0. - Bitwise complement (
~
) operator takes single operand and invert all the bits of the operand. - Bitwise right shift (
>>
) operator insert 0 bit at most significant bit and shift subsequent bits to right. - 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
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
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
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.
Read more how to use bitwise AND operator to check even or odd.
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.
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
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
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 | ' '
. Whetherch
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 whetherch
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'
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
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
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
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 ofa ^ b
i.e.c
, when XORed with a returnb
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[100]; 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: