Reputation: 67
I'm trying to understand this code which reverses bits in O(n) time. I understand the time complexity, but I'm not able to understand the logic behind this code.
public static long reverse(long a) {
long result = 0;
int i = 31;
while(a > 0){
result += (a % 2) * Math.pow(2, i);
i--;
a = a/2;
}
return result;
}
To keep it simple, for example, if I take 12 (1100) and only 4 bits (set i = 3), my output will be 3 (0011). I get that and I'm able to derive the answer as well.
But can someone explain the logic behind this code? Thanks!
Upvotes: 2
Views: 305
Reputation: 86774
That code is
a
The algorithm works only for positive numbers and does:
extract the rightmost bit from a
set the corresponding bit from the left end
shift a one position to the right
It repeats as long as a > 0
. If the value of a
has some leading zero bits then this algorithm will be a little better than O(n).
Inefficiency results from remainder and division for bit extraction when masking and shifting would be much faster, although a modern compiler should be able to convert a/2
to a >> 1
and a%2
to a & 0x00000001
. However I don't know if it would recognize Math.pow(2, i)
as 0x00000001 << i
;
Upvotes: 2
Reputation: 10653
Here's the explanation
i = 31 //number of bits in integer
Following has two parts
result += (a % 2) * Math.pow(2, i);
(a % 2)
calculates last bit.
Multiplying anything with a positive power of 2
has the effect of left shifting the bits. (Math.pow(2, i)
shifts to left i
times.
so we are calculating unit place bit and placing it at ith position from the unit place, which is (31 - i)
from the right, which effectively reverses the bit's position from left to right.
and finally
i--; //move to next bit
a = a/2; //chop the unit place bit to proceed to next.
That's it.
Upvotes: 1