给出通常能想到的方式,这两种方式在《C和指针》一书中给出。以下讨论的均为非负整数。
/* 该方法每次在循环中判断数的二进制最右一位是否为1(如果该数能不能被2整除)。 每次循环后该数右移一位。因此遍历了数的二进制表示的每一位。 */ int count_one_bits1(int value) { int count; for (count = 0; value != 0; value >>= 1) if (value % 2 != 0) count++; return count; } /* 与上边方法类似,也是每次将该数右移一位,遍历该数的二进制表示的每一位。 不过这里是将该数与1做与运算,这样,与的结果不为零则说明该数的二进制表示的最右一位为1。 */ int count_one_bits2(int value) { int count; for (count = 0; value != 0; value >>= 1) { if ((value & 1) != 0) count++; } return count; }
下面介绍另外一种方式,可以通过比上述少的比较次数来统计出数的二进制表示中1的个数。
首先作如下分析:
当一个数value是2的n(n > 0)次幂时,该数的二进制表示中必然仅在最高位包含一个1,那么value -1 的二进制形式必然是一个除了最高位其他位均为1的数;因此
value & (value - 1)的结果必然为0。那么问题来了:
可以由此得出判断数value是否是2的n次方的方法:
! (value & (value - 1))为真表示该数是2的n次幂,为假表示该数不是2的n次幂。
因此,如果某数value满足value & (value - 1) = 0,证明该数中仅包含一个1。看下面的函数:
int count_one_bits3(int value) { int count = 0; while (value) { count++; value = value & (value - 1); int v1 = value; cout << value << " "; } cout << endl; return count; }
如下图,输入value为8888,可以看出方法1执行while循环14次,方法3执行while循环6次。方法3每次循环后value的二进制中1的个数少一个。
原文地址:http://blog.csdn.net/u013074465/article/details/42617293