以下两个代码是该方法可以反转无符号32位整数的位。但是下面两个代码的区别是什么? 为什么第一个代码是错误的,第二个代码是正确的。 我看不出这两者的区别。
public int reverseBits(int n) {
int result = 0;
for (int i = 0; i < 32; i++) {
result = result << 1 | (n & (1 << i));
}
return result;
}
public int reverseBits(int n) {
int result = 0;
for (int i = 0; i < 32; i++) {
result = result << 1 | ((n >> i) & 1);
}
return result;
}
感谢任何帮助。
答案 0 :(得分:0)
它与从n抓取的位是存储在结果的最右位还是存储回相同位置有关。
答案 1 :(得分:0)
假设n
为4(例如)。
然后当i
为2时,表达式(n & (1 << i))
变为(4 & (1 << 2))
,它应该等于4 & 4
,因此它的计算结果为4。
但表达式((n >> i) & 1)
变为((4 >> 2) & 1)
,它应该等于1 & 1
,因此它的计算结果为1.
这两个表达式的结果不一样。
但是该函数的两个版本都试图以完全相同的方式使用这些结果,因此该函数的两个版本没有相同的结果。
答案 2 :(得分:0)
第一个代码是错误的,因为它提取给定位并将其放在结果数字的相同位置。假设您正在进行迭代i = 5
。然后n & (1 << 5)
= n & 32
,其为0或0b100000
。目的是将一位置于最低位置,但执行|时操作它实际上把它放到#5的相同位置。在随后的迭代中,您将此位移动得更高,因此您实际上将所有位或位于最高位位置。
请注意,有一些更有效的算法来反转位,就像在标准JDK Integer.reverse
方法中实现的那样:
public static int reverse(int i) {
// HD, Figure 7-1
i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
i = (i << 24) | ((i & 0xff00) << 8) |
((i >>> 8) & 0xff00) | (i >>> 24);
return i;
}