Каким образом (i << 48) | ((i & 0xffff0000L) << 16) | ((i >>> 16) & 0xffff0000L) | (i >>> 48) работает?

Вот реализация реверса в 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;
}

Я понимаю строки 1,2,3,4, но не 5! Как это работает?

Я группирую 64 бита в 8 групп, то есть 1 - это первые 8 бит, 2 - вторые 8 бит и так далее.

Затем после строки 4 последовательность вроде 4,3,2,1,8,7,6,5

и я думаю, что строка 5 работает, как показано ниже, до операции | :

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)

Но я не знаю, где это неправильно или неправильно! Думаю об этом почти целый день!

Кто-нибудь может мне помочь !! Спасибо.

о, я сделал такую ​​ошибку:

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)

но я также думаю, что это неправильно! Я думаю, что правильная последовательность: 8,7,6,5,4,3,2,1

Мне очень жаль, что я сделал несколько ошибок! он работает как показано ниже:

после строки 4 правильный шаблон: 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)
6
задан liuxiaori 2 March 2012 в 07:37
поделиться