We are given a 32-bit unsigned integer and need to reverse all its bits. This means the least significant bit (position 0) becomes the most significant bit (position 31), position 1 becomes position 30, and so on. It is the same idea as reversing a string, but instead of characters, we are swapping bit positions.
We always work with exactly 32 bits, even if the number is small. For example, the number 1 is 00000000000000000000000000000001 in binary. Reversing it gives 10000000000000000000000000000000, which is 2147483648. Leading zeros in the original number become trailing zeros in the result, and vice versa.
0 <= n <= 2^31 - 2 → The input is a fixed-size 32-bit value, not a variable-length one. The work is bounded by the bit width, not the magnitude of the number.n is even → The least significant bit is always 0, so the most significant bit of the result is always 0. The reversed value therefore fits in a signed 32-bit integer with no overflow into the sign bit.Reversing bits works the same way as reversing a string: read from one end and write to the other. We extract bits from the right side of the input (least significant) and place them into the result from the left side (most significant).
For each of the 32 bit positions, take the last bit of n, shift the result left by one to make room, and add that bit to the result. Then shift n right by one to expose the next bit. Because we shift the result left once per iteration, the first bit we read ends up shifted left 31 times, landing at the most significant position, which is exactly where the original least significant bit belongs.
result to 0result left by 1 to make room for the next bitn using n & 1 and OR it into resultn right by 1 to move to the next bitresultThe bit-by-bit approach runs in O(1) time, so for a single call it is fine. The follow-up asks about the case where the function is called many times, and there each call still performs 32 loop iterations. The next approach reduces the per-call work by precomputing reversals one byte at a time.
When the function is called repeatedly, we can precompute the reversal of every possible byte (8-bit value). There are only 256 possible bytes, so the lookup table is small. To reverse 32 bits, split the integer into 4 bytes, look up each byte's reversal, and reassemble them in reverse order.
This trades 256 table entries for fewer per-call operations: 4 lookups and a few shifts instead of 32 loop iterations.
Reversing 32 bits decomposes into reversing the order of the 4 bytes and reversing the bits within each byte. The table handles the within-byte reversal, and placing byte 0 in position 3, byte 1 in position 2, and so on handles the byte reordering. The original bit at position k within byte b (where b runs 0 to 3 from the low byte) ends up at position 7 - k within byte 3 - b, which is global position 8*(3 - b) + (7 - k) = 31 - (8*b + k). Since the original global position is 8*b + k, every bit lands at 31 - p, the definition of bit reversal.
table[i] is the bit-reversal of the 8-bit value iTake n = 43261596, which is 0x02941E9C. The 4 bytes from high to low are 0x02, 0x94, 0x1E, 0x9C. Each cell below holds one byte; the trace reverses each byte through the table and moves it to the mirrored position.
The lookup table speeds up repeated calls, but it requires 256 entries of precomputed data, and the 4 lookups involve memory access that can stall on a cache miss. The next approach reverses all 32 bits using only bitwise operations, with no table and no memory access.
This approach uses divide and conquer. To reverse 32 bits, first swap the left 16 bits with the right 16 bits. Then within each 16-bit half, swap the left 8 bits with the right 8 bits. Continue halving: swap 4-bit nibbles, then 2-bit pairs, then individual adjacent bits. After log2(32) = 5 swaps, every bit has moved to its reversed position.
It is the same idea as reversing a deck of cards by cutting it in half and swapping the halves, then repeating within each half, rather than moving cards one at a time.
Each step uses a bitmask to isolate the bits that move and shifts to put them in their new positions.
Track a single bit at position p (0-indexed from the right). Write p in binary using 5 bits: p = b4 b3 b2 b1 b0. The 16-bit swap flips bit b4 of the position (moving between upper and lower halves), the 8-bit swap flips b3, and so on down to the adjacent-bit swap flipping b0. After all 5 swaps, every bit of the position index has been flipped, so p becomes its bitwise complement within 5 bits, which is 31 - p. That is the definition of bit reversal.
Each swap step operates on all 32 bits at once, which is why this is called a parallel bit-reversal. It is the same permutation used in the radix-2 Fast Fourier Transform.
The code applies the swaps from coarsest to finest, halving the block size each step. The two halves of every block are isolated with a mask, shifted in opposite directions, and combined:
0x00FF00FF, shift by 8)0x0F0F0F0F, shift by 4)0x33333333, shift by 2)0x55555555, shift by 1)Take n = 43261596 = 0x02941E9C again, so the result can be compared against the other approaches. Each cell below holds one byte of the running value; the highlighted cells are the ones the current swap changes.