给定二进制数A,下面的代码求得A中1比特的个数
int get_bit1_of_binary(int A){
int count_of_bit1 = 0;
while (A) {
A &= A - 1;
count_of_bit1++;
}
return count_of_bit1;
}
分析:上面的代码的核心部分就是其中的蓝色部分的while循环部分,其主要的思想是基于如下的事实:
1. 给定二进制数A,A-1的效果是将A的所有的1比特中的最低位序的1比特及其该比特低位序的所有0取反,而其高位的比特保持不变。
2. 给定二进制数A,A与其逐位取反的数B进行位与运算则结果为0,用C语言表示即:
X=A & ~A ; //则X等于0
另外 A与其自身位与结果仍然为A,即A&A=A
A=164, 其二进制形式为:10100100,该数中的最低位序的1比特位于右数的第3位,第3位置开始的所有低比特如蓝色部分所示
A-1=163,其二进制形式为:10100011,与上面的10100100相比较,其相当于将第3位置开始的所有低比特进行了位取反操作,如蓝色部分所示,而其高位的比特保持不变
此时 A与A-1进行位与运算:A & A - 1,相当于第3位置开始的所有低比特清零,而其高位的比特保持不变即
10100100 (164)
10100011 (163)
10100000 (位与运算的结果,相当于第3位置开始的所有低比特清零,如蓝色部分所示,而其高位的比特保持不变,)
将该位与运算的结果再赋值给A,重复如上的运算,A = A & A - 1,每重复一次如上的运算过程,就将当前的最低位序的1比特进行了清零处理,相当于发现了一个1比特,循环的次数就是A中的1比特的个数 ,直到A为0结束循环,即可得到A中1比特的个数。
这个方法的执行时间仅和A中1比特的个数有关。
测试程序如下:
/*
* bit1.c
* to determine how many '1' bit in a binary number
* snallie
* 2012-11-11
*
*/
int get_bit1_of_binary(int A)
{
int count_of_bit1 = 0;
while (A) {
A &= A - 1;
count_of_bit1++;
}
return count_of_bit1;
}
void dump_binary(int A)
{
int sz=sizeof(A)*8-1;
while(sz>=0)
{
printf("%c",A&(1<<sz)?'1':'0');
sz--;
}
}
int main( int argc , char **argv)
{
int a;
if (argc<2)
{
printf("Usage: %s Integer\n",argv[0]);
exit(1);
}
a=atoi(argv[1]);
dump_binary(a);
printf(" %d\n", get_bit1_of_binary(a) );
}
运行结果:
C:\>bit1
Usage: c:/bit1.exe Integer
C:\>bit1 0
00000000000000000000000000000000 0
C:\>bit1 5
00000000000000000000000000000101 2
C:\>bit1 111
00000000000000000000000001101111 6
C:\>bit1 100
00000000000000000000000001100100 3
C:\>bit1 150
00000000000000000000000010010110 4
C:\>bit1 -1
11111111111111111111111111111111 32
--本文结束--
这篇博客介绍了如何使用3行代码计算二进制数中1比特的个数。核心思想是通过A与A-1进行位与运算,每次循环都将最低位的1比特清零,循环次数即为1比特的个数。通过示例代码和运行结果展示了解决方案的正确性和效率。
1775

被折叠的 条评论
为什么被折叠?



