求一个整数存储在内存中的二进制中1的个数

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;
}

心得体会:实现函数时,要考虑到多种测试用例,最开始写的时候就没有注意到负数,同时写的函数也要优化。通过这次练习,我对操作符有了很好的理解。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值