1.写一个函数返回参数二进制中 1 的个数
一、比如: 15 0000 1111 4 个 1 10 1010
程序原型:
int count_one_bits(int value)
{
// 返回 1的位数
}
1.模2看是否余1.要考虑负数的问题,所以在开始就直接将负数转化为无符号整数。
int count_bits1(unsigned int input)//求负数应该将数转化为无符号整型
{
int count = 0;
while (input)
{
if (input%2 == 1)
{
count++;
}
input = input / 2;
}
return count;
}
2.位运算,右移相当于除2,再和1与,将整数中的1取出来,缺点需要循环32次。
int count_bits2(int input)
{
int count = 0;
for (int i = 0; i < 32; i++)
{
if ((input >> i) & 1 == 1)//先右移在和1与,将最后一位的1取出来计数,循环32次将负数也能取出
{
count++;
}
}
return count;
}
0000 0000 0000 0000 0000 0000 0000 1111 i count
0000 0000 0000 0000 0000 0000 0000 1111 0 1
0000 0000 0000 0000 0000 0000 0000 0111 1 2
0000 0000 0000 0000 0000 0000 0000 0011 2 3
0000 0000 0000 0000 0000 0000 0000 0001 3 4
0000 0000 0000 0000 0000 0000 0000 0000 4 4
. . .
. . .
. . .
0000 0000 0000 0000 0000 0000 0000 0000 32 4
3.依次从右向左将1取出来,直到为零时跳出循环。相比于第二种方法减少了循环次数。
int count_bits3(int input)
{
int count = 0;
while (input)
{
++count;
input = (input - 1)&input;//从右向左依次将1取出,直到值为零。
}
return count;
}
主函数
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int input = 0;
scanf("%d", &input);
printf("%d %d %d\n", count_bits1(input),count_bits2(input),count_bits3(input));
system("pause");
return 0;
}
0000 0000 0000 0000 0000 0000 0000 1111 15 1
0000 0000 0000 0000 0000 0000 0000 1110 14
0000 0000 0000 0000 0000 0000 0000 1110 14 2
0000 0000 0000 0000 0000 0000 0000 1101 13
0000 0000 0000 0000 0000 0000 0000 1100 12 3
0000 0000 0000 0000 0000 0000 0000 1011 11
0000 0000 0000 0000 0000 0000 0000 1000 8 4
0000 0000 0000 0000 0000 0000 0000 0111 7
0000 0000 0000 0000 0000 0000 0000 0000 循环跳出
二、不引入中间变量实现数的交换。
int main()
{
int num1 = 1;
int num2 = 2;
printf("%d %d %d ",num1 & num2, num1 | num2, num1^num2);//操作符与 或 抑或
printf("%d ",num1>>1); //左移1位 ✖2 右移➗2
printf("%d %d\n",num1,num2);//创建变量的交换
num1 = num1 ^ num2; //3
num2 = num1 ^ num2;//1
num1 = num1 ^ num2;//2
printf("%d %d\n", num1, num2);
system("pause");
return 0;
}
心得体会:实现函数时,要考虑到多种测试用例,最开始写的时候就没有注意到负数,同时写的函数也要优化。通过这次练习,我对操作符有了很好的理解。