统计十进制数返回参数为二进制数1的个数

时间:2022-02-28 11:09:52


程序如下:

#include<stdio.h>
int main()
{
int num = 0;
int count = 0;
num = 10;
while (num)
{
if (num % 2 == 1)
{
count++;
}
num = num / 2;
}
printf("%d ", count);
system("pause");
return 0;
}</span>

但是经过测试,我们会发现,这个程序是有bug的,当我们给的变量值为复数是,结果是不正确的。比如,我们给定num=-1,执行结果为0,而我们都知道,-1在内存中存储是由补码的方式存放的,正确的结果应该为32个。


#include<stdio.h>
int main()
{
int num = 0;
int count = 0;
num = -1;
while (num)
{
if (num &1==1)
{
count++;
}
num = num >> 2;
}
printf("%d ", count);
system("pause");
return 0;
}
这个程序也是有bug的,这里我们需要知道移位分为两种:逻辑移位与算数移位,逻辑移位给最高位补0,而算数移位给最高位补符号位。此处,编译器采用的是算数移位,当num=-1时,就会出现右移一位就给最高位补1,所以上面这个程序是停不下来的。所以我们可以改成下面这样:


#include<stdio.h>
int main()
{
int num = -1234;
int count = 0;
int i = 0;
for (i = 0; i < 32; i++)
{
if ((num & 1) == 1)
{
count++;
}
num = num >> 1;
}
printf("%d\n ", count);
system("pause");
return 0;
}


#include<stdio.h>
int main()
{
unsigned int num = 0;
int count = 0;
num = -1;
while (num)
{
if (num % 2 == 1)
{
count++;
}
num = num / 2;
}
printf("%d\n ", count);
system("pause");
return 0;
}

上面这两个程序虽然都可以实现我们的目的,但是效率较低,无论是什么样的数,都要循环多次,


#include<stdio.h>
int main()
{
int num = -1;
int count = 0;
while (num)
{
count++;
num = num&(num - 1);
}
printf("%d ", count);
system("pause");
return 0;
}
为了便于利用,我们将其改写为函数形式:
#include<stdio.h>
int count_bit(int num)
{
int count = 0;
while (num)
{
count++;
num = num&(num - 1);
}
return count;
}
int main()
{
int num = -1;
int ret = count_bit(num);
printf("%d ", ret);
system("pause");
return 0;
}