Reputation: 4284
unsigned reverse_bits(unsigned input)
{
//works on 32-bit machine
input = (input & 0x55555555) << 1 | (input & 0xAAAAAAAA) >> 1;
input = (input & 0x33333333) << 2 | (input & 0xCCCCCCCC) >> 2;
input = (input & 0x0F0F0F0F) << 4 | (input & 0xF0F0F0F0) >> 4;
input = (input & 0x00FF00FF) << 8 | (input & 0xFF00FF00) >> 8;
input = (input & 0x0000FFFF) << 16 | (input & 0xFFFF0000) >> 16;
return input;
}
how does this work?
Upvotes: 12
Views: 1888
Reputation: 1769
unsigned reverse_bits(unsigned input)
{
//works on 32-bit machine
input = (input & 0x55555555) << 1 | (input & 0xAAAAAAAA) >> 1;
input = (input & 0x33333333) << 2 | (input & 0xCCCCCCCC) >> 2;
input = (input & 0x0F0F0F0F) << 4 | (input & 0xF0F0F0F0) >> 4;
input = (input & 0x00FF00FF) << 8 | (input & 0xFF00FF00) >> 8;
input = (input & 0x0000FFFF) << 16 | (input & 0xFFFF0000) >> 16;
printf("\nvalue = %x",input);
return input;
}
int _tmain()
{
// TODO: Please replace the sample code below with your own.
int value;
signed int res,bit;
signed int stPos, len;
value = 0x12345678;
reverse_bits(value);
printf("\nvalue = %x",value);
char buffer [33];
itoa (value,buffer,2);
printf ("\nbinary: %s\n",buffer);
return 0;
}
Upvotes: 0
Reputation: 5532
The code first swaps single adjacent bits, then adjacent pairs of bits, and so on, doubling the size of the swap each time until chunks half the size of the integer are swapped at the end. The swapping is done by masking off the bits to be moved with AND, shifting them and then OR'ing the results together.
The animation below is helpful for visualizing what's going on, remembering that while the swap sizes increase sequentially, all the swaps at each size occur in parallel.
Upvotes: 9
Reputation: 58598
Suppose I have a hand of 8 cards:
7 8 9 10 J Q K A
How can we reverse them? One way is to swap adjacent pairs:
8 7 10 9 Q J A K
Then, swap adjacent groups of 2: exchange 8 7 and 10 9, etc:
10 9 8 7 A K Q J
Finally, exchange groups of four, which is half the size of 8:
A K Q J 10 9 8 7
Done.
You can do this in different orders. Why? Because the exchanges are stable with respect to each other. When we exchange the upper half of the cards with the lower half, for instance, the pairs stay in the same order. Or when we exchange pairs, the halves stay in the same order.
This is what the code is doing with the bit operations. For instance to swap pairs we can use the mask 01010101 to pick out the even bits, and 10101010 to pick out the odd bits, using the bitwise AND operation:
ABCDEFGH ABCDEFGH
& 01010101 & 10101010
---------- ----------
= 0B0D0F0H A0C0E0G0
Remember, the rule for and is that given some bit value X, X & 1 = X and X & 0 = 0. The 1 bits in the mask preserve the value, and the 0 bits in the mask produce 0. This is called masking because it looks exactly like a mask used in spray-painting, etc. The 1 bits "cover" the places you don't want to "paint" with zero.
Next, the left result is shifted left one bit, and the right result shifted right. This brings about the swap:
B0D0F0H0 0A0C0E0G
Finaly, the two are combined with logical OR. The rule for OR is that X or 0 is X. The two parts each have 0 where the other has nonzero, and so the bits simply merge:
B0D0F0H0
| 0A0C0E0G
----------
= BADCFEHG
And now the pairs are swapped.
Upvotes: 18
Reputation: 41180
It can be understood by induction.
Start with the base case, a two bit number
input = (input & 0x1) << 1 | (input & 0x2) >> 1;
Now progress to a four bit number
input = (input & 0x5) << 1 | (input & 0xA) >> 1; // swap bits
input = (input & 0x3) << 2 | (input & 0xc) >> 2; // swap bit pairs
Progress to an 8 bit number
input = (input & 0x55) << 1 | (input & 0xAA) >> 1; // swap bits
input = (input & 0x33) << 2 | (input & 0xCC) >> 2; // swap bit pairs
input = (input & 0x0F) << 4 | (input & 0xF0) >> 4; // swap bit nibbles
and so on.
Upvotes: 8
Reputation: 4991
Let b[0], b[1], b[2], ..., b[31]
are bits of input
beginning from the least significant bit. Then b[1], b[0], b[3], b[2], ..., b[31], b[30]
will be bits of
input = (input & 0x55555555) << 1 | (input & 0xAAAAAAAA) >> 1;
Basically, it swaps neighboring bits of input
. Similar, other 4 lines swaps neighboring pairs, groups of 4, groups of 8, and finally groups of 16 bits.
Upvotes: 3