看到这个题目,首先想到的方法是:
int count_one_bits(unsigned int value)
{
int count=0;
while(value)
{
if(value%2==1)
{
count++;
}
value=value/2;
}
return count;
}
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num=15;
int ret=count_one_bits(num);
printf("二进制中一的个数是ret=%d\n",ret);
system("pause");
return 0;
}
上面的函数中用unsigned无符号数,所以这种方法对于负数来说解不出来,如:-1,所以进一步可以优化为:
int count_one_bits(int value)
{
int count=0;
int i=0;
for(i=0;i<32;i++)
{
if(((value>>i)&1)==1)
{
count++;
}
}
return count;
}
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num=15;
int ret=count_one_bits(num);
printf("二进制中一的个数是ret=%d\n",ret);
system("pause");
return 0;
}
若num=-1,则输出ret=32(为32个1),函数中传的数是int型,有32个bit位,所以(value>>i)&1这个表达式中数字15二进制中分别右移0位,1位,2位.........31位在按位与1,则是1的位输出1,用count计数器统计。
除了这种方法还可以用别的方法在进行优化:
int count_one_bits(int value)
{
int count=0;
while(value)
{
count++;
value=value&(value-1);
}
return count;
}
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num=-1;
int ret=count_one_bits(num);
printf("二进制中一的个数是:\nret=%d\n",ret);
system("pause");
return 0;
}
在这种方法中,表达式value=value&(value-1),每运行一次,其value二进制数中少一个最低位的1,直到value=0时可以判断出有多少个1.
而这种方法也可以推广判断一个数num是否为2^n,具体思想为if(num&(num-1)==0)则它必定为2的n次方.