且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

《计算机系统:核心概念及软硬件实现(原书第4版)》——3.1 无符号二进制表示

更新时间:2022-08-19 11:34:22

本节书摘来自华章计算机《计算机系统:核心概念及软硬件实现(原书第4版)》一书中的第3章,第3.1节,作者:[美] J. 斯坦利·沃法德(J. Stanley Warford)著, 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

3.1 无符号二进制表示

早期的计算机是机电式的,即所有计算是通过称为继电器(relay)的移动开关来实现的。哈佛大学的Howard H. Aiken(霍华德·艾肯)于1944年建造的Mark I计算机就是这种类型的机器。这个项目上,Aiken获得了国际商用机器公司(IBM)总裁Thomas J. Watson(托马斯·沃森)的资金支持。当时,Mark I计算机中的继电器比加法计算器中的机械齿轮计算速度快得多。
甚至在Mark I完成之前,艾奥瓦州立大学的John V. Atanasoff(约翰·阿塔纳索夫)已经构造完成了一台用于解线性方程的电子计算机。1941年,John W. Mauchly(约翰·莫齐利)访问Atanasoff的实验室,1946年与宾夕法尼亚大学的J. Presper Eckert(普雷斯伯·埃克特)合作建造了著名的电子数值积分计算机(ENIAC)。相比于Mark I继电器的每秒10次,ENIAC的19 000个真空管每秒可以执行5000次加法。与ENIAC一样,现代计算机也是电子的,不过执行计算的是集成电路(IC)而不是真空管。每个IC中有数千个与收音机中一样的晶体管。
3.1.1二进制存储器
电子计算机的存储器不能直接存储数字和字母,它们只能存储电子信号。当CPU从内存读取信息时,它检测到一个信号,其电压等于两节手电筒电池产生的电压。
计算机内存有一个最显著的性质:每个存储位置包含一个高电平信号或者低电平信号,绝不会是两者之间的其他信号。存储位置就像是怀孕一样,要么怀了要么没怀,没有折中的可能。
数字(digital)这个词意味着存储在内存中的信号只能有固定数量的数值。二进制意味着仅有两个可能的值。实际上,现在市场上所有计算机都是二进制的,因此每个存储位置包含一个高电平或者一个低电平,每个位置的状态也被描述为开或关,或者描述为包含1或0。
每个存储单元称为二进制数字(binary digit)或位(bit,也译作比特)。1位只能是1或0,绝不可能是其他诸如2、3、A或Z之类,这是基本概念。计算机存储器中存储的每条信息,不管是你的信用卡透支总额还是你的街道地址,都是以二进制1和0的形式存储的。

《计算机系统:核心概念及软硬件实现(原书第4版)》——3.1 无符号二进制表示


实际上,计算机存储器中的位被组合在一起形成单元(cell)。例如,一台7位的计算机会以如图3-1所示的每7位组成一组的方式存储它的信息。你可以把单元想作一组方框,每个方框包含一个1或0,除此之外什么都没有。图3-1c的前两行是不可能的,因为有些方框中的值不是0或1,最后一行也是不可能的,因为每个方框必须包含一个值。存储位不能为空。
不同计算机的每个单元中的位数不同,然而现在大多数计算机的每个单元为8位。本章给出几个单元大小不同的例子来说明普适原理。
诸如数字和字母这样的信息必须以二进制的形式表示才能存储到存储器中。用于存储信息的表示方式叫作编码(code)。本节给出存储无符号整数的编码,本章其他小节描述了存储其他类型数据的编码,下一章将分析存储器中存储程序命令的编码。
3.1.2整数
数字必须以二进制形式表示才能存储到计算机存储器中。具体的编码视这个数字有小数部分还是整数而定。如果是整数,那么编码也取决于它永远是正的还是也可以为负。
无符号二进制(unsigned binary)用于表示永远为正的整数。在学习二进制之前,我们先复习十进制(decimal或缩写dec),然后按这个方法学习二进制。
也许因为我们用10根手指计数和加法而发明了十进制,使用这个优雅规制写的算术书出现在公元8世纪的印度,它被翻译成阿拉伯文并最终被商人带到了欧洲,这里它被从阿拉伯文翻译成拉丁文。因为那时人们认为它起源于阿拉伯,所以数字被称为阿拉伯数字,但是印度-阿拉伯数字应该是更准确的名字,因为它实际上起源于印度。
以10为底的阿拉伯数字计数如下(当然是向下读):
《计算机系统:核心概念及软硬件实现(原书第4版)》——3.1 无符号二进制表示

从0开始,印度人接着发明了下一个数字1的符号,然后是2,直到符号9。这时,他们看着自己的手想到了一个神奇的点子。在最后一根手指后面,他们没有发明新的符号,而是用前面两个符号1和0一起表示下一个数字10。
剩下的故事你都知道了。当到19时,他们看到9是他们创造的符号中最高的符号了,因此他们把它降到0同时把1增加到2,这样形成20。从29到30,最终99到100,不断地继续,都是同样的处理。
如果我们仅有8个指头而不是10个将会怎样呢?到了7,下一个数字用完了最后一根手指,我们不必发明一个新符号,下一个数字会以10来表示。以8为底(八进制,octal或缩写为oct)计数是这样的:
《计算机系统:核心概念及软硬件实现(原书第4版)》——3.1 无符号二进制表示

八进制中77的下一个数字是100。
比较十进制和八进制方法,你会注意到八进制的5(oct)和十进制的5(dec)是同样的数字,但八进制21(oct)和十进制21(dec)是不一样,反而和十进制17(dec)是一样的。数字以八进制表示看上去比它们实际上以十进制表示要显得大一些。
假如我们不是有10个或者8个指头而是有3个指头会怎样呢?规律是一样的,三进制计数是这样的:
《计算机系统:核心概念及软硬件实现(原书第4版)》——3.1 无符号二进制表示

最后,我们看看无符号二进制表示。计算机仅有两根手指,以2为底(二进制,binary,或简称bin)计数遵循与八进制和三进制完全相同的方法:
《计算机系统:核心概念及软硬件实现(原书第4版)》——3.1 无符号二进制表示

二进制数看上去比它们实际的值要大很多,二进制数10110(bin)只是十进制的22(dec)。
3.1.3基本转换
给定一个二进制数,有几种方法来确定它对应的十进制数。一种方法是简单地以二进制和十进制往上数到那个数,这种方法对小的数字非常有效。另一种方法是把二进制数每个为1的位的位置值都加起来。

《计算机系统:核心概念及软硬件实现(原书第4版)》——3.1 无符号二进制表示


例3.1图3-2a展示了10110(bin)的位置值,最右边是1的位置值(称为最低有效位),每个位置值都两倍于它前面的那个位置值。图3-2b展示了得到22(dec)的加法。   □
例3.2无符号二进制类似于我们熟悉的十进制。图3-3展示了58 036(dec)的位置值。数字58 036代表6个1,3个10,没有100,8个1000和5个10 000。从最右边1的位置开始,每个位置值都10倍于它前面的位置值。在二进制中,每个位置值是两倍于它前面的那个位置值。   □
无符号数值能方便地表示为数制基底的多项式(基底也称为数制的基数(radix))。图3-4给出了10110(bin)和58 036(dec)的多项式表示。最低有效位总是基数的0次方,即1。接下来的有效位是基数的一次方,即基数本身。从多项式的结构可以看到每个位置值是前一个位置值乘以基数。

《计算机系统:核心概念及软硬件实现(原书第4版)》——3.1 无符号二进制表示


在二进制中,只有1的位置的值是奇数,所有其他位置(2的位置,4的位置,8的位置等)的值都是偶数。如果1的位置的值是0,那么二进制数的值将是几个偶数值相加的和,因此一定是偶数。另一方面,如果二进制数的1的位置的值是1,那么它的值就是把1和几个偶数值相加,因此一定是奇数。与在十进制中一样,你可以通过检测1的位置的数字很容易地确定一个二进制数是奇数还是偶数。
确定十进制数等值的二进制数有点儿棘手。一种方法是连续地把这个数除以2,保留余数的记录,余数的逆序就是这个二进制数。

《计算机系统:核心概念及软硬件实现(原书第4版)》——3.1 无符号二进制表示


例3.3图3-5把22(dec)转换成二进制。22除以2等于11,余数为0,把余数写在右列,接着11除以2等于5余1。继续进行直到商为0,这样形成一个余数列,从下往上读取余数就形成二进制数10110。    □
注意:最低有效位是用原始数字除以2得到的余数,这与仅通过检测最低有效位确定一个二进制数是奇数还是偶数是一致的。如果原始数是偶数,除以2将得到余数0,这个0将是最低有效位。相反,如果原始数是奇数,最低有效位将是1。
3.1.4无符号整数的范围
所有这些基于阿拉伯数字的计数方法都可以表示任意大的数字。然而,一个真实的计算机中每个单元的位数是有限的。图3-6展示了一个7位的单元是如何存储数22(dec)的。注意开头的两个0,它们不影响数值,但是对于指定存储器位置的内容是必需的。对于7位的计算机来说,不带方框,这个数应该写作
001 0110
开头的两个0仍然是必须要有的。本书在显示位串时,从右开始每4位一组,组间有一个空格(为了易读)。

《计算机系统:核心概念及软硬件实现(原书第4版)》——3.1 无符号二进制表示


无符号数值的范围取决于一个单元的位数。一个全0的序列代表最小的无符号值,全1的序列代表最大的。
例3.4一个7位的单元可以存储的最小无符号整数是
000 0000(bin)
可以存储的最大无符号整数是
111 1111(bin)
最小的是0(dec),最大的是127(dec)。一个7位单元不能存储大于127的无符号整数。□
3.1.5无符号加法
无符号二进制数加法和无符号十进制加法一样,只不过更容易,因为只需学习2位加法法则而不是10个数字的加法法则。位加法法则是
0+0=0
0+1=1
1+0=1
1+1=10
我们熟悉的十进制中的进位技术也一样在二进制中适用。如果一列中的两个数相加大于1,那么必须进1到下一列。
例3.5假设有一个6位的单元,把01 1010和01 0001两个数相加,简单地从最低有效位列开始把一个数写在另一个上面:
《计算机系统:核心概念及软硬件实现(原书第4版)》——3.1 无符号二进制表示

注意当到达从右数的第5列时,1+1等于10,必须写0并进1到下一列,在最后一列1+0+0得出和中最左边的1。
为了验证这个进位技术对二进制有效,把这两个数与它们的和都转换为十进制数:
01 1010(bin)=26(dec)
01 0001(bin)=17(dec)
01 1011(bin)=43(dec)
毫无疑问,在十进制中,26+17=43。    □
例3.6这些例子显示了进位可以沿着连续的列传递:
《计算机系统:核心概念及软硬件实现(原书第4版)》——3.1 无符号二进制表示

在第二个例子中,当到达从右数的第四列时,有一个来自前一列的进位,那么1 + 1 + 1等于11,必须写1并进1到下一列。 □
3.1.6 进位位
前面例子中的6位单元的表数范围是00 0000到11 1111(bin),或0到63(dec)。两个加数在表数范围内,而和不在是有可能的,这时和就太大了而不能装进6位的存储单元。
为了标记出这种情况,CPU有一个特殊的位称为进位位(carry bit),以字母C表示。当两个二进制数相加时,如果最左列(最高有效位)的和产生了一个进位,那么C被设置为1,否则C为0。换句话说,C总是包含单元最左列产生的进位。在前面所有的例子中,和都在表数范围内,所以进位位为0。
例3.7这里有两个展示进位位影响的例子:
《计算机系统:核心概念及软硬件实现(原书第4版)》——3.1 无符号二进制表示

在第二个例子中,CPU进行42 + 26的运算,正确的结果是68,但它太大不能装进6位的单元中。注意6位单元的表数范围是0到63,因此只能存储最右的6位,得到不正确的结果4,而进位位也被设置为1,表示最左一列有进位。        □
计算机对两个二进制数的减法是通过加上第二个数的负数来实现的。例如,要计算减法42-26,计算机会计算加法42+(-26)。因为没有办法存储负数,所以不可能用无符号表示两个整数的减法运算。下一节将描述存储负数的表示法。用这种表示法,C位是加上第二个数的负数的进位。