Java (i<;<;48)|((i&;0xffff0000L)<;16)|((i>;>;16)&;0xffff0000L)|(i>;>;>;48)是如何工作的?
下面是反向的详细实现:Java (i<;<;48)|((i&;0xffff0000L)<;16)|((i>;>;16)&;0xffff0000L)|(i>;>;>;48)是如何工作的?,java,long-integer,bits,Java,Long Integer,Bits,下面是反向的详细实现: public static long reverse(long i) { // HD, Figure 7-1 i = (i & 0x5555555555555555L) << 1 | (i >>> 1) & 0x5555555555555555L;//1 i = (i & 0x3333333333333333L) << 2 | (i >>> 2) &
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;
}
但是,我不知道哪里错了,也不知道是不是错了!想了差不多一整天
有人可以帮我!!谢谢
哦,我犯了这样一个错误:
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)
第1行成对交换相邻的单个位(0 1;2 3;等等)。第2-4行交换两位、4位和8位的相邻序列。此时,原始值已转换为四个16位的块,每个块与开始时相反。第5行然后重新排列4个块。基本上,第5行将两个步骤合并为一个步骤:交换两对16位块和交换一对32位块。逻辑是:
将第二个块从左侧移动到第二个块从右侧(所有其他位为零)(i>16)&0xffff0000L)
将最左侧的块移动到右侧位置(所有其他位为零)(i>>>48)
|
-ed在一起以产生最终反转。如果是分两步完成的,那么两条语句看起来就像前四条语句,但具有不同的掩码模式
我认为在第4行之后,模式是2,1,4,3,6,5,8,7
,而不是您假设的4,3,2,1,8,7,6,5
。第5行的四部分是:
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)
8,7,0,0,0,0,0-->(i((i&0xffff0000L)((i>>16)和0xffff0000L)
0,0,0,0,0,0,2,1-->(i>>>48)
您的尝试不太正确。以下是正确的版本:
2,1,4,3,6,5,8,7 --> i // Assume this sequence after line 4
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)
闻起来很头痛,我希望这不是一个面试问题!@Jerome如果面试中有人问这个问题,我宁愿离开机舱……不是面试问题。这是在java的Long.java5行中的反向方法的含义。我相信我可以在C中的一行中完成这一切:)@Jesus Ramos你能给我解释一下吗?我有什么错误吗?关于你的编辑:
6,5,8,7,2,1,4,3
是正确的输出。前4行已经将所有内容交换到8位粒度。第5行进行最后的16位和32位交换。我认为正确的输出应该是8,7,6,5,4,3,2,1
。我还认为代码是正确的elf是正确的。除了您指出的错误之外,第4行后面的模式不是OP所想的,而是2,1,4,3,6,5,8,7
(每16位块反转一次,而不是每32位块).我的问题和你的一样。为什么它在你写的时候实现。它保持相同的模式。所以一旦你理解了其中一行,你就理解了所有的行。所以没有必要“解密”最后一行。编辑:我明白为什么它是这样实现的。它节省了1个操作数。我给出的版本需要10个,而你问题中的版本只有9个…天哪…那就是你是Long.java的作者?是吗?真的是你吗???嗨,我错了,在第4行之后,模式是2,1,4,3,8,7,6,5。非常感谢!@liuxiaori-你确定吗第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)
2,1,4,3,6,5,8,7 --> i // Assume this sequence after line 4
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)
2,1,4,3,6,5,8,7 --> i // Assume this sequence after line 4
0,0,0,0,6,5,0,0 --> (i & 0xffff0000L)
0,0,6,5,0,0,0,0 --> ((i & 0xffff0000L) << 16)
2,1,4,3,6,5,8,7 --> i // Assume this sequence after line 4
0,0,2,1,4,3,6,5 --> (i >>> 16)
0,0,0,0,4,3,0,0 --> ((i >>> 16) & 0xffff0000L)
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 & 0x0000ffff0000ffffL) << 16 | (i >>> 16) & 0x0000ffff0000ffffL; // 5
i = (i & 0x00000000ffffffffL) << 32 | (i >>> 32) & 0x00000000ffffffffL; // 6
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 & 0x0000ffff0000ffffL) << 16 | (i >>> 16) & 0x0000ffff0000ffffL; // 5
i = (i << 32) | (i >>> 32) // 6