二进制及原码、反码、补码《计算机科学概论》原书第七版 重点内容分析
二进制及原码、反码、补码《计算机科学概论》原书第七版 重点内容分析
1.进制
(1)二进制
为什么计算机要使用二进制?
二进制和计算机硬件有着密切的关系。计算机硬件是通过电子电路来实现的,。计算机硬件中的电子器件(如晶体管等)可以(或者说只能)通过控制电压的高低来表示二进制的0和1。低电平信号等同于0,高电平信号等同于1。
(2)四进制、八进制与十六进制
为什么要使用四进制、八进制和十六进制?
- 其实答案非常简单,就是为了简化二进制的表达和转化。
我们以整型数(4B=32bit)为例,取一个32位的二进制数:
1010 1011 1101 1010 1011 1101 1010(32位)
再转化为四进制:
3122233122233122 (16位)
接着转化为八进制
33257325732 (11位)
接着转化为16进制
DABDABDA (8位)
我们可以明显的看出不管是哪一种都比二进制简单。
2.原码、反码
说明: 这一点在教材中没有明确说明,但其实在叙述过程中用了这些定义,所以我认为需要为各位补充这些知识(我希望各位最少看完有关原码的叙述),如果只是为了学习补码怎么转化或者只是为了考试的朋友们请直接跳转到补码的部分。
可是笔者认为:正是这些不断改进的方法和思路,更能感受到人类的智慧和计算机的绝妙。
(1)原码
转换方法
简单来说,以1字节(8bit)为例,首位的数字(我们称之为“符号位”)代表正数和负数,所有以0开头的数都为正数,以1开头的数为负数。
这一点非常的违背直觉需要重点记忆
举几个例子:
- 23用二进制原码表示为 0001 0111
- -11用二进制原码表示为1000 1011
这样就把正数和负数区分开来了。
局限性:
然而,这样表示正负数是有局限性的:
- 0的表示:
按照规定00000000表示0,10000000也表示0,同一个数却有不同的表现形式,这样就造成了混乱。 - 带有负数的计算不知道如何实现。
正是因为这样:反码和补码诞生了
(2)反码
转换方法:
对于正数来说,反码就是原码本身
对于负数来说,大概有两种方法:
(1)原码换成反码需要执行一个步骤:就是将除了符号位的数之外的其它数取反。
(2)用二进制表示负数的相反数,然后所有数取反。
局限性:
- 反码实际上是可以实现运算的,只不过运算起来有些不顺畅,所以这里就不介绍了。
- 二进制反码的依旧有两种表现形式:0000000和11111111。
因为这些局限性,我们又引出了补码的概念:
3.二进制中补码的表示法
转换方法
我们先看补码的规定,然后再详细解释为什么补码能够解决上面提出的局限。
对于正数,二进制补码就是他本身(这一点我们很好理解)。
对于负数,求二进制补码要遵循以下步骤:
- 用二进制表示这个负数的绝对值。
- 将每一个数都取反。
- 加1。
我们来举个例子,求-1的补码:
- 用二进制表示这个数的绝对值:00000001
- 将每一个数都取反:11111110
- 加1:11111111
优越性
0的问题
10000000的补码按照以上的方法表示为00000000,00000000的补码就是它本身,这样就统一了0的表示。
负数的运算
负数的运算是怎样通过补码实现的?
先说结论:在不考虑进位的情况下,补码直接直接相加,如果最高位发生进位直接舍去进位,然后按照补码的转化规则,就能知道它转化为十进制到底是多少。
解释:发生进位就说明必将有一个负数,实际上是最后的结果是正数,第一位是0
当然,以上的理解非常粗糙,让我们来具体叙述一下:
我们以我们熟悉的十进制的补码运算来叙述二进制补码运算的原理。
十进制补码实数表应该是下面的这个图:
实质就是改变了“正数与负数的相对位置”和“正负数分界线”
我们可以说是以50为轴进行对称操作将分界点从0改成了100,负数移动到了50~100的位置,设一个负数为a,那么补码的公式就是:100+a
接下来我们具体分析:
一个正数(b)一个负数(a)相加:
结果为100+a+b;
如果进位:实质是a+b>0,超过了100,进行变号,变为正数,最后的结果就是a+b。
如果不进位:那么按照图示也能得出正确答案。
同理可以理解二进制补码的运算规则,二进制补码表如下:
可以通过比较两个补码表加深理解
接下来对二进制补码运算进行举例:
接下来我们可以了解一下二进制数字在计算机中的相对位置:
4.补充知识
在X86体系下,整型数存储时,低位字节在前,高位字节在后,也就是小端字节序。
我们首先要知道什么是字节顺序:
字节顺序(byte order)也称为大小端字节序(endian),是指在存储多字节数据时字节的顺序。在计算机系统中,有两种主要的字节顺序:大端字节序(big-endian)和小端字节序(little-endian)。
- 大端字节序:将最高有效字节存储在最低的内存地址,而最低有效字节存储在最高的内存地址。
- 小端字节序:将最低有效字节存储在最低的内存地址,而最高有效字节存储在最高的内存地址。
上面的解释是什么意思呢是什么意思呢?我们来看一个例子:
比如:说以十六进制表示的0xABCDEF,在存储时实际上是EF CD AB,以8bit(1字节)为单位,较小的位数写在前,也就是地址比较高位的地址小。
举两个例子,整型(32)中的补码转换:
- 232 : 11101000 00000000 00000000 00000000
- -156: 01100100 11111111 11111111 11111111