Mohican_4/1 C语言 移位运算基本操作 计算二进制的个数

基本知识:

1.

左移运算符:  x<<k   x向左移动k位

位移运算 从左至右可结合  x<<j<<k等价于(x<<j)<<k


右移运算符:   x>>k   x向右移动k位 
逻辑右移和算术右移。
逻辑右移在左端补k个0;

算术右移是在左端补k个最高有效位:

如果符号为位1,则移入的位均为1;若符号位为0,则移入位均为0.

     

2.
C语言并没有明确定义应该使用哪种类型的右移。
对于无符号数据(unsigned声明的整形对象),右移必须是逻辑的;
对于有符号数据(默认的声明的整型对象),算术的或者逻辑的右移都可以。
然而实际上,几乎所有的编译器/机器组合都对有符号数据使用算术右移,
且许多程序员也都假设机器会使用这种右移。

问题:
1.移位运算为什么比四则运算快

移位快,只有一次寻址,逻辑运算和写操作,按位与需要两次寻址,一次逻辑运算和一次写。

2.  示例 : a<<-5 在如何表示??

某编译器测试后表示 左移27位。


/***********************************代码*****************************************/

/*********************计算一个二进制数中1的个数*******************/  
#include<stdio.h>
#include<stdlib.h>
void Count_1(int n )
{
	int count = 0;
	while (n>0)
	{
		if((n&1)==1)
		{
			count ++;
		}

		n = n>>1;
	}

	printf("the count of the number is %d \n",count);
}
/*********************移位操作的基本运算*******************/  
//去掉 - del   末位 - last  第一位 -- begin  第k位 - k  取反 -- inverse
//右边 - right   左边 — left
//1.去掉最后一位
int Del_Last(int n)
{
	n = n>>1;
	return n;
}

//2.在最后一个加0
int Last_Plus_Zero(int n)
{
	n = n<<1;
	return n;
}

//在最后加一个加1
int Last_Plus_One(int n)
{
	n = (n<<1)+1;
	return n;
}
//把最后一位变成1

int Last_Change_One(int n)
{
	n = n|1;
	return n;
}
//把最后一位变成0
int Last_Change_Zero(int n)
{
	n = (n|1)-1;
	return n;
}
//把最后一位取反
int Last_Inverse(int n)
{
	n = n^1;
	return n;
}

//把右数第k位变成1
int Right_K_One(int n,int k)
{
	n= n|(1<<(k-1));
	return n;

}
//把右数第k位变成0
int Right_K_Zero(int n,int k)
{
	n = n&~(1<<(k-1));
	return n;
}
//把右数第k位取反
int Right_K_Inverse(int n,int k)
{
	n = n^(1<<(k-1));
	return n;
}
//取末尾三位
int Last_Three(int n)
{
	n = n&((1<<n)-1);
	return n;
}
//取右边数第k位
int Right_K(int n,int k)
{
	n = n>>(k-1)&1;
	return n;
}
//把右边连续的1变成0
int Right_One_To_Zero(int n)
{
	n = n&(n+1);
	return n;
}
//把右边第一个0变成1
int Right_Zero1_To_One(int n)
{
	n = n|(n+1);
	return n;
}
//flag版 同下
//while(n%2 == 1)
//	{
//		n = n >> 1;
//		flag++;
//	}
//	n = n ^ 1;

//把右边连续的0变成1
int Right_Zero_To_One(int n)
{
	n = n|(n-1);
	return n; 
}
//	int flag= 0;
//	while(n%2 == 0)
//	{
//		n = n >> 1;
//		flag++;
//	}
//	for(int i = 0;i <flag;i++)
//	{
//		n = n << 1;
//		n = n ^ 1;
//	}
//	return n;
int main()
{
	Count_1(105); //二进制中1的个数

	char arr[10];
	itoa(Del_Last(105), arr, 2);//去掉最后一位
	printf("Del_Last --> %s\n",arr);

	itoa(Last_Plus_Zero(105), arr, 2);//在最后加一个加0
	printf("Last_Plus_Zero--> %s\n",arr);

	itoa(Right_K_One(105,4), arr, 2);//把右数第k位变成1
	printf("Right_K_One--> %s\n",arr);

	itoa(Right_Zero_To_One(105), arr, 2); //把右边连续的0变成1
	printf("Right_Zero_To_One--> %s\n",arr);

	getchar();
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值