进制、原反补码、移位操作符与位操作符~~~

这篇博客主要介绍移位操作符与位操作符,在介绍这两个操作符之前,先简要讲一下理解这两个操作符需要的基础知识——也就是二进制和原反补码!

1.进制

进制是人为规定的一种进位方法,有很多种。比如,我们日常使用的数字即为十进制。十进制逢十进一,所有数字均由0-9组成。八进制逢八进一,所有数字均由0-7组成。二进制逢二进一,所有数字均由0、1组成。十六进制逢十六进一,所有数字由0-9,a-f组成。

在日常生活中也有很多进制的例子,例如星期,逢七进一,七进制;月份逢十二进一,十二进制;小时数,逢二十四进一,二十四进制。

而计算机是一个二进制系统,数据在计算机中以二进制的形式储存。

2.整数的二进制表示

整数的二进制表示有三种,分别为原码、补码与反码。正整数的原码、补码与反码相同,而负整数的原码、补码与反码是需要计算的。

整数在内存中一般以int类型存储,int类型数据在内存中占四个字节,32个比特位,即32个二进制位。

原码是根据整数直接写出的序列。值得注意的是,二进制序列的最高位是符号位,0代表是正数,1代表是负数。

例如:7。

7的原码很简单可以写出:00000000 00000000 00000000 00000111

 

由于7为正整数,7的反码、补码与原码相同。

例如:-7

由于-7为负数,因此-7二进制序列的符号位为1,即二进制序列的最高位为1。

因此,-7的原码为:10000000 00000000 00000000 00000111

负数的补码与反码是需要计算的。

反码:原码的符号位不变,其他位按位取反即为反码。

按位取反:每一个二进制位,原值为0,则改为1;原值为1,则改为0。

因此,-7的反码:11111111 11111111 11111111 11111000

补码:反码加1即为补码。

因此,-7的补码:11111111 11111111 11111111 11111001

 

而整数在内存中是以补码存储的!!!

至此,基础的小知识就说完啦!

3.移位操作符

移位操作符移的就是我们上文所讲的二进制位

移位操作符分为(<<)左移操作符和(>>)右移操作符。

注意:1.移位操作符的操作对象只能为整数!

           2.对于移位操作符,不要移动负数位(eg. int b=a>>-1),这个是标准未定义的,不同的编译器下可能会产生不同的结果。

1.左移操作符

左移操作符:左边丢弃,右边补0(操作对象为在内存中存储的补码)。

例如,

int main()
{
	int a = 7;
	int b = a << 1;

	printf("a = %d\n", a);
	printf("b = %d\n", b);

	return 0;
}

a左移1位赋值给b,即下图:

 

因此,代码输出结果为:

  

a左移一位后,a本身不会发生变化,只会将左移一位后所得的值赋值给b。

左移之后,之前的二进制码均高了一位。因此,<<1其实有乘二的效果!

但它与乘2不同的是:<<1不会出现溢出现象,而某一个数字直接乘2所得的值可能会超过int型的范围,产生溢出现象!

2.右移操作符

右移操作符有两种移位规则,分别为逻辑移位算术移位

逻辑移位:左边用0填充,右边丢弃。

算术移位:左边用该原值的符号位填充,右边丢弃。

通常编译器中采用的是算术移位

右移一位相当于将这个数除以2!

 因此,-7右移一位后补码为:11111111 11111111 11111111 11111100

补码减1后得反码,即:11111111 11111111 11111111 11111011

除符号位按位取反得原码,即:10000000 00000000 00000000 00000100

因此,-7右移一位后得-4。

代码及输出结果为:

 同样a右移一位后,a本身不会发生变化,只会将右移一位后所得的值赋值给b。

 4.位操作符

位操作符中的位同样为二进制位!同时,位操作符操作数必须为整数!

位操作符有以下三种:

&:按位与

|:按位或

^:按位异或

1.按位与&

两数的补码对应二进制位均为1时,为1;有0时,则为0。

2.按位或

 两数的补码对应二进制位均为0时,为0;有1时,则为1。

3.按位异或

两数的补码对应二进制位相同为0,相异为1。

按位异或有如下特点:

1. a^a=0;

2. 0^a=a;

3.按位异或运算支持交换律。例如:3^3^4=3^4^3=4。

4.按位异或应用

下面说明了按位异或的两个基本小应用。

1.翻转特定的二进制位

例如:

若想将a的第二位与第四位翻转,可以将a与00001010(前三个字节省略了)进行按位异或。

2.在不使用临时变量的情况下,交换两个变量的值。

 例如:

#include <stdio.h>

int main()
{
	int a = 3;
	int b = 5;
	printf("交换前,a=%d,b=%d\n", a, b);
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("交换后,a=%d,b=%d\n", a, b);

	return 0;
}

a首先被赋值为3^5,b=a^b=3^5^5=3,a=a^3=3^5^3=5,至此完成两个变量值的交换。

5.位操作符与移位操作符的几个应用

1.统计二进制位中1的个数

//统计二进制中1的个数
#include <stdio.h>

int main()
{
	int num = 0;
	int i = 0;
	int sum = 0;
	printf("请输入一个数字:->");
	scanf("%d", &num);
	for (i = 0; i < 32; i++)
	{
		sum += (num >> i) & 1;
	}
	printf("%d中二进制中1的个数为%d\n",num,sum);

	return 0;
}

2.打印二进制位的奇数位和偶数位

#include <stdio.h>

int main()
{
	int num = 0;
	int i = 0;
	printf("请输入一个整数:->");
	scanf("%d", &num);
	for (i = 31; i >=0; i -= 2)
	{
		printf("%d", (num>>i) & 1);
	}
	printf("\n");
	for (i = 30; i>=0; i -= 2)
	{
		printf("%d", (num >> i) & 1);
	}
	printf("\n");

	return 0;
}

3.求两个数二进制位不同的个数

//求两个数二进制中不同位的个数
#include <stdio.h>

int main()
{
	int num1 = 0;
	int num2 = 0;
	int ret = 0;
	int i = 0;
	int sum = 0;
	printf("请输入两个整数:->");
	scanf("%d %d", &num1, &num2);
	ret = num1 ^ num2;
	for (i = 1; i <= 32; i++)
	{
		sum += ret & 1;
		ret >>= 1;
	}
	printf("%d", sum);
	return 0;
}

完结撒花!!!

  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值