【C语言】关于移位操作符中的原码、反码和补码

1 整数的二进制表示

整数的二进制表示有3种,分别为原码,反码和补码,而整数在内存中的是补码

        其中正整数的原码,反码和补码都是相同的。

        而负整数的原码,反码和补码都是需要计算的

相关移位操作符请见:

【C语言】基本操作符_c语言中用“_”的例子-CSDN博客


2 左移操作符 <<

左移操作符就是将整型补码向左进行移位。下列以数字7和-7为例。

	int a = 7;
	int b = a << 1;
	printf("%d\n", a);
	printf("%d\n", b);

        将整型 7 的二进制转换以后为 111,整型在内存当中占4个字节,一个字节占8bit,因此,整型 7的原码为32个bit单位。

        原码由该二进制数左端向左补零,直到补满32位数字,而第一位数字为符号位(0为整数,1为负数)。

        反码由原码符号位不变,其他位取反得到,就是当原码上的一位数字为0时,反码为1;原码为1时,反码为0。

        补码由反码加1得到这是二进制计算,不要当成十进制计算。因此可得到以下结果:(为了方便且直观数数,每4bit之间有空一格)

原码为:0000 0000 0000 0000 0000 0000 0000 0111

反码为:0000 0000 0000 0000 0000 0000 0000 0111

补码为:0000 0000 0000 0000 0000 0000 0000 0111

当对其进行左移运算的时候,是对补码进行移位的,因此需要反向计算才能得到结果。

 左移时:00000 0000 0000 0000 0000 0000 0000 1110

        左边丢弃右边补0原码符号位不变

因此,左移得到补码的结果为:

0000 0000 0000 0000 0000 0000 0000 1110

反码为:0000 0000 0000 0000 0000 0000 0000 1110

原码为:0000 0000 0000 0000 0000 0000 0000 1110

因此结果为14。


 由此可知,-7的原码,反码和补码分别如下:

原码为:1000 0000 0000 0000 0000 0000 0000 0111

反码为:1111 1111 1111 1111 1111 1111 1111 1000

补码为:1111 1111 1111 1111 1111 1111 1111 1001

左移时:11111 1111 1111 1111 1111 1111 1111 0010

左边丢弃右边补0原码符号位不变

补码为:1111 1111 1111 1111 1111 1111 1111 0010

反码为:1111 1111 1111 1111 1111 1111 1111 0001

原码为:1000 0000 0000 0000 0000 0000 0000 1110

因此结果为-14。


3 右移操作符<<

右移操作符与左移操作符的原理类似,就是在右移的过程的时候,关于右边添加的数字当中有两种方法,一种是直接补零(也就是逻辑移位),一种是补原符号位(算术移位)。这些补位方法与编译器有关,不同的编译器的补位方法是不同的。本文使用的编译器为VS 2022,是算术移位的方法。右移操作符依旧以7和-7为例,方法与左移相似。

	int c = 7;
	int d = c >> 1;
	printf("%d\n", c);
	printf("%d\n", d);

当7向右移位时:

右移时:0000 0000 0000 0000 0000 0000 0000 00111

        右边丢弃(左边补0)原码符号位不变

补码为:0000 0000 0000 0000 0000 0000 0000 0011

反码为:0000 0000 0000 0000 0000 0000 0000 0011

原码为:0000 0000 0000 0000 0000 0000 0000 0011

因此结果为3。

 当-7向右移位时:

右移时:1111 1111 1111 1111 1111 1111 1111 1100​​​1

右边丢弃(左边补0)原码符号位不变

补码为:1111 1111 1111 1111 1111 1111 1111 1100

反码为:1111 1111 1111 1111 1111 1111 1111 1011

原码为:1000 0000 0000 0000 0000 0000 0000 0100

因此结果为-4。

你可能感兴趣的:(C语言,c语言,开发语言,学习,笔记)