简单二进制位移编程题

1. 
写一个函数返回参数二进制中 1 的个数 
比如: 15 0000 1111 4 个 1 
程序原型: 
int count_one_bits(unsigned int value) 

// 返回 1的位数 

难点和改良方法已写在注释上

#include<stdio.h>
#include<windows.h>

int count_one_bits(unsigned int value)
{
	int count = 0;
	int i = 0;
	for (i = 0; i<31; i++)   //int型的二进制表示范围有32位,要将这三十二位全部右移检测一次
		//除了这种方法,还能用while(value)的方式进行循环,因为value每次右移都会左端补一个0,当value等于0时退出循环,故最多循环32次
	{
		if (value & 1 == 1)  //这里利用的是value和二进制的1(0001)进行对比,如果末尾是1,则&结果是1,通过判断count的数量就能判断1的个数
			//此处可改进为(value>>i)&1==1(利用的是位移操作符不会改变自身的值,而i++每次加1),则可省略value=value>>1不写
		{
			count++;
			value=value >> 1;   //位移操作符和自加自减不同,并不会改变自身的值,所以需要value=value >> 1
		}
	}
	return count;
}
int main()
{
	int a = 15;
	printf("数字%d的二进制中1的个数为为%d\n", a, count_one_bits(a));
	system("pause");
	return 0;
}

在&运算中还有一种比较难想到的方法可以统计1的个数,那就是用n = n & (n - 1) 

首先是(n - 1)发生了什么:

二进制数n,n-1后,如果最后一位是0,将向前一位借2,2-1=1。最后一位为1。如果前一位为0,将继续向前一位借2,加上本身少掉的1.则变为1。一直遇到1。减为0.

所以 二进制 xxxx10000-1 = xxxx01111

n&n-1产生的结果:

按照上述 n=xxxx10000,n-1=xxxx01111

xxxx10000

xxxx01111

xxxx00000

这里可以看出进行了&运算后,最后一位1被消去了

重复操作,有多少个1,这个操作就可以执行多少次。
 

2.获取一个数二进制序列中所有的偶数位和奇数位, 
分别输出二进制序列。 

将所有比特位逐个右移的方法在上面的例子中已经用过,虽然比较直观,但是麻烦,本例用while(n>0)的方法进行循环

#include<stdio.h>
int print(int n)
{
	int i = 0;
	int m = n >> 1;
	//输出偶数位
	/*for (i = 31; i > 0; i = i - 2){
		printf("%d ", (n >> i) & 1);
	}*/
	while (n > 0){
		printf("%d", n & 1);
		n = n >> 2;
	}
	printf("%\n");
	//输出奇数位
	/*for (i = 30; i >= 0; i = i - 2){
		printf("%d ", (n >> i) & 1);
	}*/
	while (m > 0){
		printf("%d", m & 1);
		m = m >> 2;
	}
}
int main(){
	int i = 9;
	print(i);
	return 0;
}

3.两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同? 
输入例子: 
1999 2299 
输出例子:7

#include<stdio.h>
int main(){
	int a = 1999;
	int b = 2299;
	int c = a^b; 
	//异或运算,二进制中有几个1就有几个位(bit)不同
	//然后统计1的个数就能知道有几位(bit)不同
	int count = 0;
	while (c > 0){
		if (c % 2 == 1)
			++count;
		c = c >> 1;
	}
	printf("%d\n", count);
	return 0;
}

(@_@;)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值