This is a problem from leetcode( https://leetcode.com/problems/number-of-1-bits/ ). This method is for counting the 1s this number has in binary. I try to use n=n/2 which doesn't pass every case while n=n>>1 does. Does anyone know why??
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;
}
}
>> 1
divides an int
by two, but the rounding is done using floor, ie rounding towards negative infinity. The relevant quote from the Java Language Specification:
The value of n >> s is n right-shifted s bit positions with sign-extension. The resulting value is floor(n / 2^s).
For example,
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)
On the other hand, for /
the rounding is done towards zero. This is from the Java Language Specification:
The binary / operator performs division, producing the quotient of its operands. The left-hand operand is the dividend and the right-hand operand is the divisor.
Integer division rounds toward 0.
For example,
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)
For negative odd integers n
, n /= 2
is therefore the same as n >>= 1; n++;
n >>= 1; n++;
. The n++
will completely change the calculation for the number of set bits.
You're using unsigned ints. 0xFFFFFFFF = -1. -1 >> 1 = -1. -1/2 = 0. It will fail for any number with the most significant bit set.
If Java, the >>
operator does a sign-extended bitwise right shift. For example (I use 8 bits digits for clarity's sake):
0b10111111 >> 1 => 0b11011111
The same in decimal:
-65 >> 1 => -33
Bits are shifted right by one position, and the most significant bit is kept as is. My example number (0b10111111) is -65 in decimal. If you divide it by two, you get -32. Yes, we've lost one bit in translation. /2
performs an arithmetic division, which is equivalent to >> 1
only for positive numbers.
In languages that support unsigned ints and an unsigned right shift, n/2 should work as intended.
In java, since >>
is signed, you could use >>>
which does a right shift without sign extension, and the possibly faster loop:
public int hammingWeight(int n) {
int count = 0;
while(n != 0) {
if ((n & 1) != 0) {
count++;
}
n = n >>> 1;
}
return count;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.