这是来自leetcode(https://leetcode.com/problems/number-of-1-bits/)的问题。 此方法用于计算此数字以二进制表示的1。 我尝试使用n = n / 2,它不通过每种情况,而n = n>> 1。有谁知道为什么??
public class Numberof1Bits {
public static void main(String[] args) {
System.out.println(new Numberof1Bits()
.hammingWeight(0b11111111111111111111111111111111));
}
public int hammingWeight(int n) {
int count = 0;
if (n < 0)
count++;
for (int i = 0; i < 31; i++) {
if ((n & 1) == 1)
count++;
n = n >> 1;// while this doesn't work when n=n/2;
}
return count;
}
}
答案 0 :(得分:2)
>> 1
将int
除以2,但是使用floor进行舍入,即向负无穷大舍入。 Java语言规范的相关引用:
n的值>&gt; s是n右移位s位 符号扩展。结果值为floor(n / 2 ^ s)。
例如,
20 >> 1 == 10
15 >> 1 == 7 (7.5 is rounded down to 7)
-20 >> 1 == -10
-15 >> 1 == -8 (-7.5 is rounded down to -8)
另一方面,对于/
,舍入是朝向零。这来自Java语言规范:
二元/运算符执行除法,产生它的商 操作数。左手操作数是红利和右手 操作数是除数。
整数除法向0舍入。
例如,
20 / 2 == 10
15 / 2 == 7 (7.5 is rounded down to 7)
-20 / 2 == -10
-15 / 2 == -7 (-7.5 is rounded UP to -7)
对于负奇数整数n
,n /= 2
因此与n >>= 1; n++;
相同。 n++
将完全改变设置位数的计算。
答案 1 :(得分:1)
您使用的是无符号整数。 0xFFFFFFFF = -1。 -1&gt;&gt; 1 = -1。 -1/2 = 0.对于设置了最高有效位的任何数字,它将失败。
如果是Java,>>
运算符会执行符号扩展的按位右移。例如(为清楚起见,我使用8位数字):
0b10111111 >> 1 => 0b11011111
十进制相同:
-65 >> 1 => -33
位向右移动一个位置,最高位保持原样。我的示例编号(0b10111111)是十进制的-65。如果将它除以2,则得到-32。是的,我们在翻译中丢失了一点。 /2
执行算术除法,相当于正数的>> 1
。
在支持无符号整数和无符号右移的语言中,n / 2应该按预期工作。
在java中,由于>>
已签名,您可以使用>>>
执行右移而不使用符号扩展,以及可能更快的循环:
public int hammingWeight(int n) {
int count = 0;
while(n != 0) {
if ((n & 1) != 0) {
count++;
}
n = n >>> 1;
}
return count;
}