Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does (i << 48) | ((i & 0xffff0000L) << 16) | ((i >>> 16) & 0xffff0000L) | (i >>> 48) work?

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)
like image 916
liuxiaori Avatar asked Mar 02 '12 06:03

liuxiaori


People also ask

What is the meaning of 1 << J in C++?

In more detail, 1 << j uses shifting of 1 to generate a bit mask in which only the j -th bit is set. The & operator then masks out the j -bit of counter ; if the result is not zero (which means that the j -th bit of counter was set), the condition is satisfied.

What does 1 << 0 do in C?

1 << 0 is 1 shifted to the left by 0 positions, which is just 1.

What does << mean in coding?

The << operator shifts the left-hand value left by the (right-hand value) bits. Your example does nothing! 1 shifted 0 bits to the left is still 1. However, 1 << 1 is 2, 1 << 2 is 4, etc.

What does a << B mean?

a<<b for integers means "shift left". The bitwise representation of a is shifted left b bits. This is the same as multiplying by (2 to the power of b ).


1 Answers

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, not 4,3,2,1,8,7,6,5 as you assumed. The four pieces of line 5 then are:

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)
like image 66
Ted Hopp Avatar answered Oct 26 '22 19:10

Ted Hopp