C Bit Manipulation Techniques

Every integer in C is stored as a sequence of bits (0s and 1s) in memory. Bit manipulation means directly reading, setting, clearing, or toggling individual bits inside that integer using bitwise operators. These techniques are extremely fast because they happen at the hardware level in a single CPU instruction.

Bit manipulation is heavily used in embedded systems, device drivers, cryptography, compression, and competitive programming.

Quick Recap: Bitwise Operators

OperatorSymbolEffect
AND&1 only if both bits are 1
OR|1 if at least one bit is 1
XOR^1 only if bits differ
NOT~Flips all bits
Left Shift<<Shifts bits left (multiply by 2)
Right Shift>>Shifts bits right (divide by 2)

Core Bit Manipulation Techniques

Technique 1: Check If a Bit is Set

Use AND with a mask that has only the target bit set. If the result is non-zero, the bit is 1.


To check bit position n of number x:
mask = 1 << n
result = x & mask

If result != 0 → bit n is SET (1)
If result == 0 → bit n is CLEAR (0)
#include <stdio.h>

int isBitSet(int num, int pos)
{
    return (num & (1 << pos)) != 0;
}

int main()
{
    int x = 13;   // binary: 1101

    printf("Bit 0: %d\n", isBitSet(x, 0));   // 1 (set)
    printf("Bit 1: %d\n", isBitSet(x, 1));   // 0 (clear)
    printf("Bit 2: %d\n", isBitSet(x, 2));   // 1 (set)
    printf("Bit 3: %d\n", isBitSet(x, 3));   // 1 (set)

    return 0;
}

x = 13 = 0000 1101
          bit: 3210

Bit 0: 1101 & 0001 = 0001 → non-zero → SET
Bit 1: 1101 & 0010 = 0000 → zero    → CLEAR
Bit 2: 1101 & 0100 = 0100 → non-zero → SET

Technique 2: Set a Bit (Turn ON)

Use OR with a mask. OR with 1 always gives 1 regardless of the current bit value.

x = x | (1 << n);   // set bit n of x to 1
#include <stdio.h>

int main()
{
    int x = 8;   // binary: 1000
    x = x | (1 << 1);   // set bit 1

    // 1000 | 0010 = 1010 = 10
    printf("After setting bit 1: %d\n", x);   // Output: 10

    return 0;
}

Technique 3: Clear a Bit (Turn OFF)

Use AND with the complement (~) of the mask. AND with 0 always gives 0.

x = x & ~(1 << n);   // clear bit n of x to 0
#include <stdio.h>

int main()
{
    int x = 13;   // binary: 1101
    x = x & ~(1 << 2);   // clear bit 2

    // ~(0100) = 1011
    // 1101 & 1011 = 1001 = 9
    printf("After clearing bit 2: %d\n", x);   // Output: 9

    return 0;
}

Technique 4: Toggle a Bit (Flip)

Use XOR with a mask. XOR with 1 always flips the bit.

x = x ^ (1 << n);   // toggle bit n
#include <stdio.h>

int main()
{
    int x = 13;   // binary: 1101

    x = x ^ (1 << 1);   // toggle bit 1
    // 1101 ^ 0010 = 1111 = 15
    printf("After toggle 1: %d\n", x);   // Output: 15

    x = x ^ (1 << 1);   // toggle bit 1 again
    // 1111 ^ 0010 = 1101 = 13
    printf("After toggle 2: %d\n", x);   // Output: 13 (back to original)

    return 0;
}

Useful Bit Tricks

Check If a Number is Even or Odd

if (n & 1)
    printf("Odd\n");
else
    printf("Even\n");
// The last bit is 1 for odd numbers, 0 for even numbers

Multiply and Divide by Powers of 2

int x = 5;
printf("%d\n", x << 1);   // 10  (5 * 2)
printf("%d\n", x << 2);   // 20  (5 * 4)
printf("%d\n", x >> 1);   // 2   (5 / 2 — integer)

Swap Two Numbers Without a Temp Variable

int a = 5, b = 9;
a ^= b;   // a = 5 ^ 9 = 12
b ^= a;   // b = 9 ^ 12 = 5
a ^= b;   // a = 12 ^ 5 = 9
// Now a = 9, b = 5

Check If a Number is a Power of 2

A power of 2 in binary has exactly one bit set (e.g., 4 = 0100, 8 = 1000). Subtracting 1 flips all bits below that bit. ANDing gives 0.

int isPowerOf2(int n)
{
    return (n > 0) && ((n & (n - 1)) == 0);
}
// isPowerOf2(8)  = 1 (yes)
// isPowerOf2(6)  = 0 (no)
// isPowerOf2(16) = 1 (yes)

Count Set Bits (Hamming Weight)

int countSetBits(int n)
{
    int count = 0;
    while (n)
    {
        count += n & 1;   // add 1 if last bit is set
        n >>= 1;           // shift right by 1
    }
    return count;
}
// countSetBits(13) → 13 = 1101 → 3 set bits

Find the Rightmost Set Bit

int rightmostSetBit(int n)
{
    return n & (-n);   // isolates the lowest set bit
}
// n=12 = 1100: -12 in two's complement has lowest bit at position 2
// 1100 & 0100 = 0100 = 4  (bit position 2)

Turn Off the Rightmost Set Bit

n = n & (n - 1);
// 12 = 1100: 12 & 11 = 1100 & 1011 = 1000 = 8

Bit Fields in Structures

Bit fields let you pack multiple small values into a single integer, saving memory.

#include <stdio.h>

struct Flags {
    unsigned int isAdmin    : 1;   // 1 bit — 0 or 1
    unsigned int isVerified : 1;   // 1 bit — 0 or 1
    unsigned int level      : 4;   // 4 bits — 0 to 15
};

int main()
{
    struct Flags user;
    user.isAdmin    = 1;
    user.isVerified = 1;
    user.level      = 7;

    printf("Admin: %d, Verified: %d, Level: %d\n",
           user.isAdmin, user.isVerified, user.level);
    // Output: Admin: 1, Verified: 1, Level: 7

    printf("Size: %lu bytes\n", sizeof(user));   // 4 bytes (one int)
    return 0;
}

Practical Bit Manipulation Reference

TaskCode
Check bit n(x >> n) & 1
Set bit nx |= (1 << n)
Clear bit nx &= ~(1 << n)
Toggle bit nx ^= (1 << n)
Is odd?x & 1
Is power of 2?(x > 0) && !(x & (x-1))
Multiply by 2^nx << n
Divide by 2^nx >> n
Swap a and ba^=b; b^=a; a^=b;
Count set bitsLoop with n &= n-1

Summary

Bit manipulation techniques let you read, set, clear, and toggle individual bits inside an integer using bitwise operators. Checking a bit uses AND with a shifted mask. Setting a bit uses OR. Clearing uses AND with the NOT of the mask. Toggling uses XOR. These techniques produce faster and more memory-efficient code than arithmetic equivalents, especially in embedded systems and performance-critical applications. Bit fields in structures allow packing multiple flags into a single integer. The ability to manipulate individual bits is a sign of deep C programming expertise and is indispensable in systems-level development.

Leave a Comment

Your email address will not be published. Required fields are marked *