Here is the implementation of reverse in Long:
public static long reverse(long i) {
// HD, Figure 7-1
i = (i & 0x5555555555555555L) << 1 | (i >>> 1) & 0x5555555555555555L;//1
i = (i & 0x3333333333333333L) << 2 | (i >>> 2) & 0x3333333333333333L;//2
i = (i & 0x0f0f0f0f0f0f0f0fL) << 4 | (i >>> 4) & 0x0f0f0f0f0f0f0f0fL;//3
i = (i & 0x00ff00ff00ff00ffL) << 8 | (i >>> 8) & 0x00ff00ff00ff00ffL;//4
i = (i << 48) | ((i & 0xffff0000L) << 16) |
((i >>> 16) & 0xffff0000L) | (i >>> 48);//5
return i;
}
I can understand line 1,2,3,4, but not 5! How does it work?
I group the 64 bits to 8 groups,that is 1 is the first 8 bits, 2 is the second 8 bits, and so on.
Then after line 4,the sequence like 4,3,2,1,8,7,6,5
and I think line 5 working as below before the | operation:
6,5,0,0,0,0,0,0-->(i << 48)
8,7,0,0,0,0,0,0-->((i & 0xffff0000L) << 16)
0,0,0,0,4,3,2,1-->((i >>> 16) & 0xffff0000L)
0,0,0,0,0,0,2,1-->(i >>> 48)
But, I don’t know where dose it wrong or whether it is wrong! Thinking about it almost about a whole day!
Somebody can help me!! Thanks.
oh, i made a mistake like this:
6,5,0,0,0,0,0,0-->(i << 48)
0,0,8,7,0,0,0,0-->((i & 0xffff0000L) << 16)
0,0,0,0,2,1,0,0-->((i >>> 16) & 0xffff0000L)
0,0,0,0,0,0,4,3-->(i >>> 48)
but i alse think it is wrong! i think the right sequence is 8,7,6,5,4,3,2,1
i am so sorry that i make some mistakes! it works right as below:
after line 4, the right pattern is:2,1,4,3,6,5,8,7
8,7,0,0,0,0,0,0-->(i << 48)
0,0,6,5,0,0,0,0-->((i & 0xffff0000L) << 16)
0,0,0,0,4,3,0,0-->((i >>> 16) & 0xffff0000L)
0,0,0,0,0,0,2,1-->(i >>> 48)
Line 1 swaps adjacent single bits in pairs (0 <-> 1; 2 <-> 3; etc.). Lines 2-4 swaps adjacent sequences of two bits, 4 bits, and 8 bits. At that point, the original value has been transformed into four blocks of 16 bits with each block the reverse of what it had been at the start. Line 5 then rearranges the 4 blocks. Basically, line 5 combines two steps into one: swapping two pairs of 16-bit blocks and swapping one pair of 32-bit blocks. The logic is:
(i << 48)moves the rightmost 16-bit block to the left position, leaving all other bits zero((i & 0xffff0000L) << 16)moves the second block from the right to be the second block from the left (all other bits zero)((i >>> 16) & 0xffff0000L)moves the second block from the left to be the second block from the right (all other bits zero)(i >>> 48)moves the leftmost block to the right position (all other bits zero)Then these four values are
|-ed together to produce the final reversal. If it had been done in two steps, it would be two statements that look just like the first four statements, but with different mask patterns.I think that after line 4, the pattern is
2,1,4,3,6,5,8,7, not4,3,2,1,8,7,6,5as you assumed. The four pieces of line 5 then are: