I found this snippet on 'codefights' submitted by a programmer. My solution to the problem was 30 lines, whereas this is just a beauty. But I am not able to understand the logic. Can anyone explain this.
int mirrorBits(int a) {
int r = 0;
for (; a; a >>= 1)
r = r << 1 | a & 1;
return r;
}
input a = 8; output : 1
First of all, there is a very good StackOverflow answer here: Most Efficient Algorithm for Bit Reversal ( from MSB->LSB to LSB->MSB) in C
The algorithm makes use of
>> ... binary shift right (100b >> 1 == 10b)
<< ... binary shift left (100b << 1 == 1000b
| .... binary or (100b | 10b == 110b)
& .... binary and (111b & 100b == 100b)
The for loop shifts a to the right until all bits have fallen out of a.
Imagine you start with a = 101101 then a >>= 1 does the following:
At the end of loop 1: a == 10110
At the end of loop 2: a == 01011
At the end of loop 3: a == 00101
At the end of loop 4: a == 00010
At the end of loop 5: a == 00001
At the end of loop 6: a == 00000 (condition fails -> loop ends)
The body of the loop shifts b one bit right, uses & to mask the last bit of a and adds it as last digit to b. The or can be used to add the last digit because << inserts 0 for all "new" bits.
Imagine you start with a = 101101
In detail the inner loop #3 does the following: (a is 001011 and r is 010)
r << 1 changes r from 010 to 0100. The last digit is the inserted 0. a & 1 masks the current last bit from a (the 1 in 00101 1 ) now we have (0100 | 1) which has the result 0101.
Warning : This algorithm is not really mirroring the bits, because you do not get the original value if you apply the algorithm to the result.
If you need a mirrored 32-bit unsigned integer you have to loop 32 times independently of the value of a:
unsigned int r = 0;
unsigned int a = 12345;
for(int i = 0; i < 32; ++i)
{
r = (r << 1) | (a & 1);
a >>= 1;
}
If you apply this algorithm twice, you should get the original value.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.