← All Posts
DSA · Bit Manipulation· Part 11 of 32

Bit Reversal, Rotation, and Byte Tricks

Some bit problems are about individual flags. Others are about rearranging whole bit layouts: reversing a 32-bit integer, rotating a word, swapping nibbles, or packing bytes. These patterns show up in interviews, hashing, compression, cryptography, graphics, and low-level systems code.

Reverse Bits with a Loop

The straightforward method shifts the answer left and appends the current low bit of the input.

uint32_t reverse_bits(uint32_t x) {
    uint32_t ans = 0;
    for (int i = 0; i < 32; ++i) {
        ans = (ans << 1) | (x & 1u);
        x >>= 1;
    }
    return ans;
}

This is O(width), which is constant for fixed-width integers and perfectly acceptable in interviews.

SWAR Reversal

SWAR means "SIMD within a register." Instead of processing one bit at a time, swap adjacent groups: bits, then pairs, then nibbles, then bytes, then half-words.

uint32_t reverse_bits_swar(uint32_t x) {
    x = ((x & 0x55555555u) << 1) | ((x >> 1) & 0x55555555u);
    x = ((x & 0x33333333u) << 2) | ((x >> 2) & 0x33333333u);
    x = ((x & 0x0f0f0f0fu) << 4) | ((x >> 4) & 0x0f0f0f0fu);
    x = ((x & 0x00ff00ffu) << 8) | ((x >> 8) & 0x00ff00ffu);
    return (x << 16) | (x >> 16);
}

Rotations

A rotation shifts bits around a circle. Unlike a normal shift, no bits are lost; bits shifted out on one side re-enter from the other side.

uint32_t rotl32(uint32_t x, int k) {
    k &= 31;
    return (x << k) | (x >> ((32 - k) & 31));
}

uint32_t rotr32(uint32_t x, int k) {
    k &= 31;
    return (x >> k) | (x << ((32 - k) & 31));
}

In C++20, prefer std::rotl(x, k) and std::rotr(x, k) from <bit>.

Byte and Nibble Swaps

Hexadecimal makes byte tricks easier to read because two hex digits are one byte and one hex digit is one nibble.

// Swap high and low nibbles in an 8-bit value.
uint8_t swap_nibbles(uint8_t x) {
    return (x << 4) | (x >> 4);
}

// Reverse byte order in a 32-bit value.
uint32_t bswap32(uint32_t x) {
    return ((x & 0x000000ffu) << 24) |
           ((x & 0x0000ff00u) << 8)  |
           ((x & 0x00ff0000u) >> 8)  |
           ((x & 0xff000000u) >> 24);
}

Endianness Basics

Endianness is about byte order in memory, not the mathematical value. The integer 0x12345678 has the same value on every machine, but its bytes may be stored as 12 34 56 78 (big endian) or 78 56 34 12 (little endian).

Interview rule: do not bring endianness into normal arithmetic problems unless the question explicitly asks about memory layout, serialization, networking, or byte arrays.

When These Tricks Matter

Practice Problems