解法一:
思路:把整数减去1就是把最右边的1变成0,如果它右边还有0的话就把所有的0变成1,而它左边的所有位都保持不变。接下来把该整数和它减去1的结果做按位与运算,相当于把它最右边的1变成0。那么一个整数的二进制表示中有多少个1,就可以进行多少次这样的操作。
eg:value & (value-1)
15转换成二进制 0000 1111
1111 & 1110 = 1110
1110 & 1101 = 1100
1100 & 1011 = 1000
1000 & 0111 = 0000
#include<stdio.h>
int count_bit(unsigned int value)
{
int count=0;
while(value)
{
count++;
value=value & (value-1);
}
return count;
}
int main()
{
int ret = 0;
ret = count_bit(7);
printf("%d\n",ret);
return 0;
}
解法二
//常规解法,左移1
int NumOf1(int n)
{
int count = 0;
int flag = 1;
while (flag)
{
if (n & flag)
count++;
flag <<= 1;
}
return count;
}
int main()
{
int n = -1;
int ret = NumOf1(n);
cout << ret << endl;
getchar();
return 0;
}
解法三:
右移value,当value为负数时会产生死循环。因为:在c语言中左移也就是所说的逻辑移位,右端补0,而右移是算数移位,左端补齐的是最高位的符号位。
故负数左移,有可能变成正数,但负数右移,肯定还是负数。
eg:-1用十六进制的补码表示为:0xFFFFFFFF,-1右移一位任然是0xFFFFFFFF
#include<stdio.h>
int count_bit(unsigned int value)
{
int count=0;
while(value)
{
//把整数右移一位和把整数除以2在数学上是等价的,但是除法的效率比移位运算要低得多
if((value & 1) == 1)
//if(value % 2==1)
{
count ++;
value = value >> 1;
}
}
return count;
}
int main()
{
int ret = 0;
ret = count_bit(15);
printf("%d\n",ret);
return 0;
}