The following code deomnstrates a divide and conquer approach for bit counting using 3-bit grouping. This method efficiently computes the number of set bits in an integer by breaking the problem into smaller subproblems, solving them individually, and then combinnig the results.
public static int bitsCount(int x) {
int n;
n = (x >>> 1) & 033333333333;
x = x - n;
n = (n >>> 1) & 033333333333;
x = x - n;
x = (x + (x >>> 3)) & 030707070707;
return x % 63;
}
This algorithm divides the 32-bit integer into 11 groups of 3 bits each. The leftmost group may have only 2 bits, which is padded with a zero to make it 3 bits. Each group is processed independently, and the results are combined to form the final count.
The core principle involves subtracting shifted values from the original to calculate the sum of bits within each 3-bit segment. A mask (033333333333 in octal) ensures that each group is isolated during processing.
The first part of the algorithm handles the decomposition and individual calculation of each group. The second part merges the results from these groups into a final count using bitwise operations and modular arithmetic.
The mask 030707070707 in octal is used to combine adjacent groups into larger segments, and the modulo operation (x % 63) is used to finalize the result by summing all segments.
Below is a comparison of different bit counting implementations:
public class BitsCountBTest {
public static int bitCountShiftRB(int i) {
i = (i & 0x55555555) + ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i & 0x0F0F0F0F) + ((i >>> 4) & 0x0F0F0F0F);
i = (i * (0x01010101)) >> 24;
return i;
}
public static int bitCount(int i) {
i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i + (i >>> 4)) & 0x0f0f0f0f;
i = i + (i >>> 8);
i = i + (i >>> 16);
return i & 0x3f;
}
public static int bitsCount3bit(int x) {
int n;
n = (x >>> 1) & 033333333333;
x = x - n;
n = (n >>> 1) & 033333333333;
x = x - n;
x = (x + (x >>> 3)) & 030707070707;
return x % 63;
}
public static void printXB(int x) {
System.out.println("x=" + x + " bitCount: " + bitCount(x));
System.out.println("x=" + x + " bitsCount3bit: " + bitsCount3bit(x));
System.out.println("x=" + x + " bitCountShiftRB: " + bitCountShiftRB(x));
}
public static void main(String[] args) {
int x = 0B01111010010101010010000111110010;
printXB(x);
x = 13;
printXB(x);
x = 39;
printXB(x);
x = 377;
printXB(x);
x = 0XB90D8B1B;
printXB(x);
}
}
All implementations produce consistent results.