How to find hamming weight in java
The Hamming weight of a number is the count of bits set to 1 in its binary representation. It's also called the popcount (population count) or bit count. This concept comes up in coding interviews, error detection algorithms, and low-level programming.
5in binary is101→ Hamming weight = 28in binary is1000→ Hamming weight = 1255in binary is11111111→ Hamming weight = 8
Real-World Uses
- Error detection/correction: Hamming codes use bit counts to detect and correct transmission errors
- Cryptography: Many algorithms work with bit patterns and their weights
- Feature similarity: Hamming distance measures similarity between binary feature vectors in ML
- Chess engines: Bitboards represent piece positions; popcount tells you how many pieces are on the board
Three Approaches in Java
Method 1: Division and Remainder
public static int hammingWeightDivision(int n) {
int count = 0;
while (n > 0) {
if (n % 2 == 1) {
count++;
}
n = n / 2;
}
return count;
}
How it works: Each division by 2 right-shifts the number by one bit. The remainder (n % 2) is 1 if the least significant bit was set. The loop ends when all bits are consumed (n reaches 0).
Limitation: Doesn't handle negative integers correctly — the loop exits at 0, missing the sign bit.
Method 2: Bit Masking
public static int hammingWeightBitMask(int n) {
int count = 0;
int mask = 1;
for (int i = 0; i < 32; i++) {
if ((n & mask) != 0) {
count++;
}
mask <<= 1; // shift mask left by one position
}
return count;
}
How it works: The mask starts at 00000000...00000001 and shifts left by one bit each iteration, visiting all 32 positions. (n & mask) != 0 tells us whether that specific bit is set.
Advantage: Works correctly for all 32 bits including the sign bit — handles negative integers.
Method 3: Brian Kernighan's Algorithm (Most Elegant)
This technique exploits the fact that n & (n-1) always clears the lowest set bit of n:
public static int hammingWeightKernighan(int n) {
int count = 0;
while (n != 0) {
n = n & (n - 1); // clears the lowest set bit
count++;
}
return count;
}
Walkthrough for n = 12 (binary 1100):
n = 1100 → n-1 = 1011 → n & (n-1) = 1000 (count=1)
n = 1000 → n-1 = 0111 → n & (n-1) = 0000 (count=2)
n = 0 → loop exits
Why it's elegant: It only iterates as many times as there are set bits. If only 2 bits are set in a 64-bit number, it runs 2 iterations — not 64.
Complete Example
public class HammingWeight {
public static int byDivision(int n) {
int count = 0;
while (n > 0) {
if (n % 2 == 1) count++;
n = n / 2;
}
return count;
}
public static int byBitMask(int n) {
int count = 0;
int mask = 1;
for (int i = 0; i < 32; i++) {
if ((n & mask) != 0) count++;
mask <<= 1;
}
return count;
}
public static int byKernighan(int n) {
int count = 0;
while (n != 0) {
n = n & (n - 1);
count++;
}
return count;
}
public static void main(String[] args) {
int[] tests = {0, 1, 5, 8, 15, 255};
for (int val : tests) {
System.out.printf("%-6d → bitMask=%-3d kernighan=%-3d builtin=%d%n",
val, byBitMask(val), byKernighan(val), Integer.bitCount(val));
}
}
}
Output:
0 → bitMask=0 kernighan=0 builtin=0
1 → bitMask=1 kernighan=1 builtin=1
5 → bitMask=2 kernighan=2 builtin=2
8 → bitMask=1 kernighan=1 builtin=1
15 → bitMask=4 kernighan=4 builtin=4
255 → bitMask=8 kernighan=8 builtin=8
Built-in Java Method
Java provides Integer.bitCount() in java.lang — no import needed. It uses a hardware-level POPCNT instruction on modern CPUs and is significantly faster than any manual implementation:
System.out.println(Integer.bitCount(5)); // 2
System.out.println(Integer.bitCount(255)); // 8
System.out.println(Integer.bitCount(Integer.MAX_VALUE)); // 31
System.out.println(Long.bitCount(Long.MAX_VALUE)); // 63
For production code, always use Integer.bitCount(). The manual implementations are valuable for learning and interview contexts.
Comparing All Approaches
| Method | Time Complexity | Handles Negatives | Notes |
|---|---|---|---|
| Division & Remainder | O(log n) | No | Most readable; fails on negative ints |
| Bit Masking | O(32) = O(1) | Yes | Always 32 iterations |
| Brian Kernighan | O(popcount) | Partial | Fastest when few bits set |
Integer.bitCount() | O(1) | Yes | Uses hardware instruction; use in production |
Bonus: Hamming Distance
The Hamming distance between two integers is the number of bit positions where they differ. It's computed with XOR (which marks differing bits) followed by a popcount:
int hammingDistance(int x, int y) {
return Integer.bitCount(x ^ y);
}
System.out.println(hammingDistance(1, 4)); // 0001 ^ 0100 = 0101 → 2
System.out.println(hammingDistance(3, 5)); // 011 ^ 101 = 110 → 2