user-0 提问: 求算法高手看看这个题目的意思:如何以最快的速度计算出一个二进制数中1的个数

回复:
user: user-1
content: 引用 9 楼 KenZhang1031 的回复:将n写成二进制形式，然后相邻位相加，重复这个过程，直到只剩下一位。以123为例，二进制为1111101，如下图：  不用分开加，直接按位都加一遍更方便。

user: user-2
content: 这个比6楼的还慢, 顶楼的最快..  引用 3 楼 xwhbwas2008 的回复:这个方法好点  8bit静态表查找法 Precompute_8bit       static int bits_in_char [256] = {                   0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2,      3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3,      3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3,      4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4,      3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5,      6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4,      4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5,      6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5,      3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3,      4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6,  6, 7, 6, 7, 7, 8  };             int bitcount (unsigned int n)       {          // works only for 32-bit ints          return bits_in_char [n           & 0xffu]              +bits_in_char [(n >>8) & 0xffu]              +bits_in_char [(n >> 16) & 0xffu]              +bits_in_char [(n >> 24) & 0xffu] ;       }  使用静态数组表，列出所有8bit(256个)无符号数含有Bit1的个数。将32Bit 的n分4部分，直接在表中找到对应的Bit1的个数，然后求和。  这是最快的方法了。缺点是需要比较大的内存。

user: user-3
content: Hacker's Delight

user: user-4
content: 见《高效程序的奥秘》。

user: user-0
content: 这个方法好点  8bit静态表查找法 Precompute_8bit       static int bits_in_char [256] = {                   0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2,      3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3,      3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3,      4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4,      3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5,      6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4,      4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5,      6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5,      3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3,      4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6,  6, 7, 6, 7, 7, 8  };             int bitcount (unsigned int n)       {          // works only for 32-bit ints          return bits_in_char [n           & 0xffu]              +bits_in_char [(n >>8) & 0xffu]              +bits_in_char [(n >> 16) & 0xffu]              +bits_in_char [(n >> 24) & 0xffu] ;       }  使用静态数组表，列出所有8bit(256个)无符号数含有Bit1的个数。将32Bit 的n分4部分，直接在表中找到对应的Bit1的个数，然后求和。  这是最快的方法了。缺点是需要比较大的内存。

user: user-5
content: 将n写成二进制形式，然后相邻位相加，重复这个过程，直到只剩下一位。以123为例，二进制为1111101，如下图：

user: user-6
content: 这题在编程之美上提过 n=(n&MASK1)+((n>>1)&MASK1)算出的是相邻的两位中1的个数。 n=6二进制表示为0110 n&MAKS1=0100 n>>1&MASK=0001 n=(n&MASK1)+((n>>1)&MASK1)=0101 表示6的前两位中有一个1后两位中有一个1 同理n = (n & MASK2) + ((n >> 2) & MASK2); 算出相邻的四位有多少个1同样在上面的结果为例n=0010 接着就是相邻的8位。。

user: user-7
content: 引用 6 楼 Inhibitory 的回复:[quote=引用 4 楼 iamkconghua 的回复:]  //将x转化为2进制，计算含有的1的个数 int GetNumOfOne(int x) { 	int count = 0; 	while (x) 	{ 		count++; 		x = x & (x - 1); 	} 	return count; }   原理：一个数减去1，则这个数的二进制数种最后一个1及其后的数字取反。 x & (x - 1)为它的二进制数中少一个1[/quote]  这个解法没看过那个面试题的，一般人肯定想不到。

user: user-1
content: 引用 4 楼 iamkconghua 的回复: //将x转化为2进制，计算含有的1的个数 int GetNumOfOne(int x) { 	int count = 0; 	while (x) 	{ 		count++; 		x = x & (x - 1); 	} 	return count; }   原理：一个数减去1，则这个数的二进制数种最后一个1及其后的数字取反。 x & (x - 1)为它的二进制数中少一个1

user: user-8
content: 上述解法源自 微软 的一道面试题

user: user-8
content: //将x转化为2进制，计算含有的1的个数 int GetNumOfOne(int x) { 	int count = 0; 	while (x) 	{ 		count++; 		x = x & (x - 1); 	} 	return count; }

user: user-9
content: 各位相加得出的值是1的个数，这个是一个并行的加法。