写一个函数返回参数二进制中 1 的个数。
比如: 15 0000 1111 4 个 1
我们先引入一个容易理解的例子,怎么得到一个十进制的数各个位置上的数为多少?
这里我们以一个十进制的三位数 123为例,要想得到它的个位,十位,百位都为多少我们要进行如下操作:
同理得到123的二进制各二个位置上的数位多少进行如下操作:
所以我们可以得到第一种方法:
#include<stdio.h>
int fun1(int number) {
int count = 0;
while (number!=0)
{
if (number % 2 == 1) {
count++;
}
number = number / 2;
}
return count;
}
int main() {
int num = 0;
int sum = 0;
scanf("%d", &num);
sum=fun1(num);
printf("%d的二进制中有%d个1",num,sum);
return 0;
}
但是这种方法不适用于负数,因此要对形参进行修改为无符号数
#include<stdio.h>
int fun1(unsigned int number) {//修改成无符号数,添加unsigned
int count = 0;
while (number!=0)
{
if (number % 2 == 1) {
count++;
}
number = number / 2;
}
return count;
}
int main() {
int num = 0;
int sum = 0;
scanf("%d", &num);
sum=fun1(num);
printf("%d的二进制中有%d个1",num,sum);
return 0;
}
第二种方法:
使用右移操作符,对补码进行移位,再让移位后的数和1进行按位与操作,结果若为1则个数加一
1的32位2进制为00000000000000000000000000000001
具体流程如下:
代码:
#include<stdio.h>
int fun1(int number) {
int count = 0;
for (int i = 0; i < 32; i++)
{
//if ((number >> i )% 2 == 1) {//这样算不适用于负数,因为存的是补码,%2的时候用的是原码,多思考一下
// count++;
//}
if (((number >> i) &1) == 1) {
count++;
}
}
return count;
}
int main() {
int num = 0;
int sum = 0;
scanf("%d", &num);
sum = fun1(num);
printf("%d的二进制中有%d个1", num, sum);
return 0;
}
第三种方法:
思路:由最低位向最高位依次将1变为0,这种做法更多的是观察,总结出规律
代码:
#include<stdio.h>
int fun1(int number) {
int count = 0;
while (number!=0)
{
number = number & (number - 1);
count++;
}
return count;
}
int main() {
int num = 0;
int sum = 0;
scanf("%d", &num);
sum = fun1(num);
printf("%d的二进制中有%d个1", num, sum);
return 0;
}