原理1:
32位的二进制统计个数,只需要用6位数来表示,最多是0b100000
16位的二进制统计个数,只需要用5位数来表示,最多是0b10000
8位的二进制统计个数,只需要用4位数来表示,最多是0b1000
4位的二进制统计个数,只需要用3位数来表示,最多是0b100
2为的二进制统计个数,只需要用2位数来表示,最多是0b10
原理2:
二进制的乘法受到位数的限制,如32位的乘法,可能出现越乘越小的情况,或者说乘法溢出。
刚好按照8位分数的32位二进制,乘以24(0b00000001000000010000000100000001),会导致高8位的结果等于相加,当然次8位因为最大是00001000,只相加三次,不会溢出到高8位。
所以高8位的和,刚好就是32为的二进制统计个数。
package suanfa; public class HanmmingWeight { public static void main(String[] args) { int i = 0b10101010101010101010101011111111; System.out.println(swar(i)); } static int swar(int i) { System.out.println(Integer.toString((i & 0x55555555), 2)); System.out.println(Integer.toString(((i >> 1) & 0x55555555), 2)); i = (i & 0x55555555) + ((i >> 1) & 0x55555555); System.out.println(Integer.toString(i, 2)); System.out.println(); System.out.println(Integer.toString((i & 0x33333333), 2)); System.out.println(Integer.toString(((i >> 2) & 0x33333333), 2)); i = (i & 0x33333333) + ((i >> 2) & 0x33333333); System.out.println(Integer.toString(i, 2)); System.out.println(); System.out.println(Integer.toString((i & 0x0F0F0F0F), 2)); System.out.println(Integer.toString(((i >> 4) & 0x0F0F0F0F), 2)); i = (i & 0x0F0F0F0F) + ((i >> 4) & 0x0F0F0F0F); System.out.println(Integer.toString(i, 2)); System.out.println(); System.out.println(Integer.toString(i * (0x01010101), 2)); i = (i * (0x01010101) >> 24); System.out.println(Integer.toString(i, 2)); return i; } }