例题
写一个函数返回参数二进制中 1 的个数。
比如: 15 0000 1111
4 个 1
比较容易想到的方法
十进制的1234想拿到最低位可以1234%10=4拿到最低位的4,然后1234/10变成123.然后重复上面的方法拿到4 3 2 1
二进制想拿到最低位方法类似:
比如13的二进制表示是1101,
13%2=1,13/2=6
6%2=0,6/2=3
3%2=1,3/2=1
1%2=1,1/2=0
就可以拿到1011
int count_one_bit(int num)
{
int count = 0;
while (num)
{
if (num % 2 == 1)
{
count++;
}
num /= 2;
}
return count;
}
这个算法对负数有点问题,我们可以改进一下:
int count_one_bit(unsigned int num)
{
int count = 0;
while (num)
{
if (num % 2 == 1)
{
count++;
}
num /= 2;
}
return count;
}
移位操作符和位运算符结合:
int count_one_bit(int num)
{
int count = 0;
int i = 0;
for (i = 0; i < 32; i++)
{
if (((num >> i) & 1) == 1)
{
count++;
}
}
return count;
}
n=n&(n-1)的方法:
int count_one_bit(int num)
{
int count = 0;
while (num)
{
num = num & (num - 1);
count++;
}
return count;
}
int main()
{
int num = 0;
scanf("%d", &num);//10 20 15 -1
int ret = count_one_bit(num);
printf("%d\n", ret);
return 0;
}
两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同?
移位操作符和位运算符结合:
int main()
{
int m = 0;
int n = 0;
int i = 0;
scanf("%d %d", &m, &n);
int count = 0;
for (i = 0; i < 32; i++)
{
if (((m >> i) & 1) != ((n >> i) & 1))
{
count++;
}
}
printf("%d\n", count);
return 0;
}
n=n&(n-1)和异或结合:
int main()
{
int m = 0;
int n = 0;
int i = 0;
scanf("%d %d", &m, &n);
int count = 0;
//异或 - 相同为0,相异为1
//010
//001
//011
int ret = m ^ n;
while (ret)
{
ret = ret & (ret - 1);
count++;
}
printf("%d\n", count);
return 0;
}
如何判断一个数是不是 2 的幂次方?
2 的幂次方 的数:二进制中只有1个1
2 - 10
4 - 100
8 - 1000
…
那么可以用 n&(n-1) == 0 让这个数的二进制消失一个1