2 2⋯⋯⋯ 0
第 3 版 · OCR 辅助 · 原书检索 · 文字用于定位,公式与图表请回原页核验 · 本次导入快照
### 2 2⋯⋯⋯ 0
### 2 1⋯⋯⋯⋯1
高位
0
第2章
25
<!-- page: 43 -->
计算机组成与系统结构(第 3版)
26
所以,135=2070=1000 0111B。
2)小数部分的转换
小数部分的转换方法是“乘基取整,上高下低”。也就是说,用要转换的十进制小数去乘
以基数R,将得到的乘积的整数部分作为结果数据中各位的数字,小数部分继续与基数R
相乘。以此类推,直到某一步乘积的小数部分为0或已得到希望的位数为止。最后,将上面
的整数部分作为左边高位上的数位,下面的整数部分作为右边低位上的数位。
例2.4 将十进制小数0.6875分别转换成二进制数和八进制数。
解:
(高位)
0.6875×2=1.375
整数部分=1
0.375×2=0.75
整数部分=0
0.75×2=1.5
整数部分=1
0.5×2=1.0
整数部分=1
(低位)
所以,0.6875=0.1011B。
0.6875×8=5.5
整数部分=5
(高位)
0.5×8=4.0
整数部分=4
(低位)
所以,0.6875=0.54O。
在转换过程中,可能乘积的小数部分总得不到0,即转换得到希望的位数后还有余数,
这种情况下得到的是近似值。
例2.5 将十进制小数 0.63转换成二进制数。
解:
0.63×2=1.26
整数部分=1
(高位)
0.26×2=0.52
整数部分=0
0.52×2=1.04
整数部分=1
0.04×2=0.08
整数部分=0
(低位)
所以,0.63=0.1010⋯B。
3)含整数、小数部分的数的转换
只要将整数部分和小数部分分别进行转换,得到转换后相应的整数和小数部分,然后再
将这两部分组合起来得到一个完整的数。
例2.6 将十进制数135.6875分别转换成二进制数和八进制数。
解:只需将例2.3和例2.4的结果合起来,即135.6875=10000111.1011B=207.54O。
3.二、八、十六进制数的相互转换
将十六进制或八进制数转换成二进制数时,只要按照表2.1中数的对应关系,把每一个
十六进制或八进制数字改写成等值的4位或3位二进制数即可,且保持高低位的次序不变。
例2.7 将十六进制数 2B.5EH 转换成二进制数。
解:2B.5EH=0010 1011.0101 1110B=101011.0101111B。
将二进制数转换成十六进制或八进制数时,整数部分从低位向高位方向每4位或3位
用一个等值的十六进制或八进制数字来替换,最后不足4位或3位时在高位补0凑满4位
或3位;小数部分从高位向低位方向每4位或3位用一个等值的十六进制或八进制数字来
替换,最后不足4位或3位时在低位补0凑满4位或3位。例如:
11001.11B=0001 1001.1100B=19.CH;11001.11B=011001.110B=31.6O。
<!-- page: 44 -->
数据的机器级表示
4.十进制整数转换为二进制整数的简便方法
二进制数的权从小到大分别是1(2°),2(21),4(22),8(23),16(2?),32(2?),64(2?),
128(2?),256(2*),512(2*),1024(21),2048(211),4096(212),8192(213),16384(21?),
32768(2l?),65536(21),⋯。利用这些二进制数中第n位上的权,可以快速将一个十进制数
转换为二进制数。
假设被转换十进制数为x,先确定最接近x的权2”。
(1)若x大于或等于2”,则按以下方式转换:求x和最接近权的差,再确定小于该差值
并最接近该差值的权;再求差,再找小于该差值并最接近差值的权;⋯⋯;一直到差为0为
止;将这些权对应数位上置1,其他位为0,得到的便是转换后的二进制数。
(2)若x小于2",则按以下方式转换:求2"-1和x的差d;然后按(1)中的方式确定d
的二进制表示;最后将2"-1减去d,即可得到最终的二进制表示。
例2.8 将十进制数 8261转换成二进制数。
解:最靠近8261的权是8192,8261-8192=69;69-64=5;5-4=1;1-1=0。因为8192=
21,64=2?,4=22,1=2°,故第0,2,6,13位为1,其余位为0,即结果为10 0000 0100 0101B。
例2.9 将十进制数8161转换成二进制数。
解:最靠近8161的权是8192,d=8192-1-8161=30;30-16=14;14-8=6;6-4=2;
2-2=0。d 对应的二进制数为11110,故结果为11111 1111 1111-11110=1 1111 1110 0001B。
二进制数与十六进制数之间有简单、直观的对应关系。因此,如果要将十进制数转换为
十六进制数,可以先按简便方法转换为二进制数,然后再将二进制数转换为十六进制数。这
比将十进制数直接转换为十六进制数更简单。
二进制数太长,书写、阅读均不方便;十六进制数却像十进制数一样简练,易写易记。虽
然计算机中只使用二进制一种记数制。但为了在开发和调试程序、查看机器代码时便于书
写和阅读,人们经常使用十六进制来等价地表示二进制,所以必须熟练掌握十六进制数的表
示及其与二进制数之间的转换。
##### 2.1.3 定点和浮点表示
日常生活中所使用的数值数据有整数和实数之分,整数的小数点固定在数的最右边,可
以省略不写,而实数的小数点则不固定。计算机内部数据中每一位只能是0或1,不可能出
现小数点,因此,要使得计算机能够处理日常使用的数值数据,必须要解决小数点的表示问
题。通常计算机中通过约定小数点的位置来实现。小数点位置约定在固定位置的称为定点
数,小数点位置约定为可浮动的称为浮点数。
因为任意一个浮点数都可以用一个定点小数和一个定点整数来表示,所以,只需要考虑
定点数的编码表示。
2.1.4定点数的编码
因为计算机内部数据中每一位只能是0或1,所以正/负号也用0和1来表示。一般规
定0表示正号,1表示负号。数字化了的符号能否和数值部分一起参加运算呢?为了解决
这个问题,就产生了把符号位和数值部分一起进行编码的各种方法。
通常将在计算机内部编码表示后的数称为机器数,而机器数真正的值(即现实世界中带
第2章
27
<!-- page: 45 -->
计算机组成与系统结构(第3版)
28
有正负号的数)称为机器数的真值。例如,-10(一1010B)用8位补码表示为11110110,说
明机器数11110110B(F6H或0xF6)的真值是一10,或者说,-10的机器数是11110110B。
关于补码表示将在本节介绍。根据定义可知,机器数一定是一个0/1序列,通常缩写成十六
进制形式。
假设机器数X的真值Xr的二进制形式(即式中X’=0或1,0≤i≤n-2)如下:
Xr=±X'-2⋯X{X。(当X为定点整数时)
Xr=±0.X'-2⋯X{X6(当X为定点小数时)
对Xr用n位二进制数编码后,机器数X表示为
X=X-Xn-z⋯X?X?
机器数X有n位,式中X,=0或1,0≤i≤n-1,其中,第一位X,-i是数的符号,后n-1位
X。-2⋯X:X。是数值部分。数值数据在计算机内部的编码问题,实际上就是机器数X的
各位X,的取值与真值Xr的关系问题。
在上述对机器数X及其真值X7的假设条件下,下面介绍带符号定点数的原码、补码、
反码和移码表示方法。
1.原码表示法
一个数的原码表示由符号位直接跟数值位构成,因此,也称“符号-数值(sign and
magnitude)”表示法。原码表示法中,正数和负数仅符号位不同,数值部分完全相同。
原码编码规则如下:
(1)当X+为正数时,X-=0,X,=X′(0≤i≤n-2);
(2)当Xr为负数时,X。-?=1,X,=X′(0≤i≤n-2)。
原码 0有两种表示形式:
[+0]w=0 00⋯0
[一0]=1 00⋯0
根据原码定义可知,对于数-10(一1010B),假定用8位原码表示,则n=8,真值X=
一0001010,机器数X为1000 1010B(8AH或0x8A);对于数-0.625(一0.101B),若用8位
原码表示,则其机器数为1101 0000B(DOH或OxD0)。
原码表示的优点是,与真值的对应关系直观、方便;其缺点是,0的表示不唯一,给使用
带来不便,并且原码运算中符号和数值部分必须分开处理。
2.补码表示法
补码表示可以实现加减运算的统一,即用加法来实现减法运算。在计算机中,补码用来
表示带符号整数。补码表示法也称“2-补码”(two's complement)表示法,由符号位后跟上
真值的模 2”补码构成,因此,在介绍补码概念之前,先讲一下有关模运算的概念。
1)模运算
在模运算系统中,若A、B、M满足下列关系:A=B+K×M(K为整数),则记为A=
B(mod M)。即A、B各除以M后的余数相同,故称B和A为模M同余。也就是说在一
个模运算系统中,一个数与它除以“模”后得到的余数是等价的。
钟表是一个典型的模运算系统,其模为12。假定现在钟表时针指向10点,要将它拨向
6点,则有以下两种拨法。
(1)逆时针拨4格:10-4=6。
<!-- page: 46 -->
数据的机器级表示
(2)顺时针拨8格:10+8=18=6(mod12)。
所以在模12系统中,10-4=10+(12-4)=10+8(mod12),即-4=8(mod 12)。
称8是一4对模12的补码。同样有-3=9(mod 12);-5=7(mod 12)等。
由上述例子与同余的概念,可得出如下的结论:对于某一确定的模,某数A 减去小于
模的另一数B,可以用 A加上一B的补码来代替。这就是为什么补码可以借助加法运算来
实现减法运算的道理。
例2.10 假定在钟表上只能顺时针方向拨动时针,如何用顺拨的方式实现将10点倒拨
4格?拨动后钟表上是几点?
解:钟表是一个模运算系统,其模为12。根据上述结论,可得
10-4=10+(12-4)=10+8=6(mod 12)
因此,可从10点顺时针拨8(一4的补码)格来实现倒拨4格,最后是时针指向6点。
例2.11 假定算盘只有4挡,且只能做加法,则如何用该算盘计算9828-1928 的结果?
解:这个算盘是一个“4位十进制数”模运算系统,其模为10°。根据上述结论,可得
9828-1928=9828+(101-1928)=9828+8072=7900(mod 101)
因此,可用9828加8072(-1928的补码)来实现 9828 减1928 的功能。
显然,在只有4挡的算盘上运算时,如果运算结果超过4位,则高位无法在算盘上表示,
只能用低 4位表示结果,留在算盘上的值相当于是除以模(101)后的余数。
推广到计算机内部,n位运算部件就相当于只有n挡的二进制算盘,其模就是2"。
计算机中的存储、运算和传送部件都只有有限位,相当于有限挡数的算盘,因此计算机
中所表示的机器数的位数也只有有限位。两个n位二进制数在进行运算过程中,可能会产
生一个多于n位的结果。此时,计算机和算盘一样,也只能舍弃高位而保留低n位,这样做
可能会产生两种结果。
(1)剩下的低n位数不能正确表示运算结果,即丢掉的高位是运算结果的一部分。例
如,在两个同号数相加时,当相加得到的和超出了n位数可表示的范围时出现这种情况,则
称此时发生了“溢出”(overflow)现象。
(2)剩下的低n位数能正确表示运算结果,即高位的舍去并不影响其运算结果。在两
个同号数相减或两个异号数相加时,运算结果就是这种情况。舍去高位的操作相当于“将
一个多于n位的数去除以2”,保留其余数作为结果”的操作,也就是“模运算”操作。如例2.11
中最后相加的结果为17900,但因为算盘只有4挡,最高位的1自然丢弃,得到正确的结
果7900。
2)补码的定义
根据上述同余概念和数的互补关系,可引出补码的表示:正数的补码符号为0,数值部
分是它本身;负数的补码等于模与该负数绝对值之差。
因此,数 Xr的补码可用如下公式表示:
(1)当Xr为正数时,[X-]=Xr=M+Xr(mod M);
(2)当X?为负数时,[Xr]=M-|Xr|=M+X?(mod M)。
综合(1)和(2),得到以下结论:对于任意一个数Xr,[Xr]n=M+Xr(mod M)。
对于具有一位符号位和n—1位数值位的n位二进制整数补码来说,其补码定义如下:
[X?]*=2"+Xr(-2-1≤Xr<2*-',mod 2")
第2章
29
<!-- page: 47 -->
计算机组成与系统结构(第3版)
3)特殊数据的补码表示
30
通过以下例子来说明几个特殊数据的补码表示。
例2.12 分别求出补码位数为n和n+1时—2°-I的补码表示。
解:当补码的位数为n位时,其模为2",因此:
[-2*-|]=2*-2*-1=2*-'(mod 2")=10⋯0 (n-1个0)
当补码的位数为n+1位时,其模为2"+1,因此:
[-2*-`]=2"+1-2*-1=2"+2"-'(mod 2*+)=110⋯0 (n-1个0)
从该例可以看出,同一个真值在不同位数的补码表示中,其对应的机器数不同。因此,在给
定编码表示时,一定要明确编码的位数。在机器内部,编码的位数就是机器中运算部件的
位数。
例2.13 设补码的位数为n,求一1的补码表示。
解:对于整数补码有
[-1]#=2"-1=11⋯1 (n个1)
若考虑小数一1.0的补码表示,则根据补码定义有
[-1.0]=2-1.0=1.0⋯0(n-1个0)
上述补码中的小数点“.”在机器中实际上是不存在的,只是书写时为了将定点小数和定点整
数的编码区分开来而加上的,因此当补码位数为n时,-1.0和—2"-'的补码表示完全相同,
都是符号位为1,数值部分为n-1个0。这是因为一1.0和-2*-1分别是n位补码小数和n
位补码整数中可表示的最小负数。不过,现代计算机中多采用IEEE754标准表示浮点数,
其中的定点小数采用原码表示,因此通常不会涉及定点小数的补码表示。
对于n位补码表示来说,2*'的补码为多少呢?根据补码定义,有
[2*-']=2*+2"-'(mod 2*)=2"-+=10⋯0 (n-1个0)
最高位为1,说明对应的真值是负数,而这与实际情况不符,显然n位补码无法表示2*~1。
由此可知,为什么在n位二进制整数补码定义中,真值的取值范围包含了—2”-1,但不
包含 2*-'。
例2.14 求0的补码表示。
解:根据补码的定义,有
[+0]#=[-0]*=2"±0=1 00⋯0(mod 2")=0 0⋯0 (n个0)
从上述结果可知,0的补码表示是唯一的。这带来了以下两方面的好处。
(1)减少了+0和一0之间的转换。
(2)少占用一个编码表示,使补码比原码能多表示一个最小负数。在n位原码表示的
定点数中,100⋯0用来表示-0,但在n位补码表示中,一0和+0都用00⋯0表示。因此,
正如例2.12所示,100⋯0可用来表示最小负整数—2*-'。
4)补码与真值之间的转换方法
原码与真值之间的对应关系简单,只要对符号转换,数值部分不需改变。但对于补码来
说,正数和负数的转换不同。根据定义,求一个正数的补码时,只要将正号转换为0,数值部
分无须改变;求一个负数的补码时,需要做减法运算,因而不太方便和直观。
例2.15 设补码的位数为8,求1101100和—110 1100的补码表示。
解:补码的位数为8,说明补码数值部分有7位,根据补码定义,知:
<!-- page: 48 -->
数据的机器级表示
[110 1100]#=2*+110 1100=1 0000 0000+110 1100(mod 2*)=0110 1100
[-110 1100]=2?-110 1100=1 0000 0000-110 1100
=1000 0000+1000 0000—110 1100
=1000 0000+(111 1111-110 1100)+1
=1000 0000+001 0011+1(mod 2*)=1001 0100
本例中是两个绝对值相同、符号相反的数。其中,负数的补码计算过程中,第一个1000 0000
用于产生最后的符号1,第二个1000 0000拆为1111111+1,而(1111111—110 1100)实际
是将数值部分110 1100各位取反。模仿这个计算过程,不难从补码的定义推导出负数补码
计算的一般步骤为:符号位为1,数值部分“各位取反,末位加1”。
因此,可以用以下简单方法求一个数的补码:对于正数,符号位取0,其余同真值中相应
各位;对于负数,符号位取1,其余各位由数值部分“各位取反,末位加1”得到。
例2.16 假定补码位数为8,用简便方法求 X=-110 0011的补码表示。
解:[X]=1001 1100+0 000 0001=1 001 1101。
对于由负数补码求真值的简便方法,可以通过以上求负数的补码的简便方法得到。可
以对补码数值部分先减1然后再取反,得到真值的数值部分。也就是说,通过计算1111111—
(001 1101-1)得到数值部分为110 0011,该计算可以变为(111 1111-001 1101)+1,亦即
进行“取反加1”操作。
因此,由补码求真值的简便方法为:若符号位为0,则真值的符号为正,其数值部分不变;
若符号位为1,则真值的符号为负,其数值部分由补码数值部分“各位取反,末位加1”得到。
例2.17 已知[Xr]#=10110100,求真值Xr。
解:X?=-(100 1011+1)=-100 1100。
根据上述有关补码和真值转换规则,不难发现,根据补码[Xr]*求[-Xr]的方法是:对
[X?]“各位取反,末位加1”。这里要注意最小负数取负后会发生溢出。
例2.18 已知[Xr]=1011 0100,求[—X-]。
解:[-Xr]=0 100 1011+0 000 0001=0 100 1100
例2.19 已知[X-]#=1000 0000,求[—X-]#。
解:[-Xr]w=0 111 1111+0 000 0001=1 000 0000(结果溢出)
例2.19中出现了“两个正数相加,结果为负数”的情况,因此,结果是一个错误的值,称
结果“溢出”,该例中,8位整数补码10000000对应的是最小负数-2',对其取负后的值为2'
(即128)。因为8位整数补码能表示的最大正数为2'-1=127,显然,128无法用8位补码
表示,即结果溢出。
在结果溢出时,有的编译器不会作任何提示,因而可能会得到意想不到的结果。
5)变形补码
为了便于判断运算结果是否溢出,某些计算机中还采用了一种双符号位的补码表示方
式,称为变形补码,也称为模4-补码。在双符号位中,左符是真正的符号位,右符用于判断
“溢出”。
假定变形补码的位数为n+1(其中符号占2位,数值部分占n-1位),则变形补码可如
下表示:
[Xr]#=2"+1+X(-2"-1≤Xr<2*-1,mod 2"+1)
第2章
31
<!-- page: 49 -->
计算机组成与系统结构(第3版)
32
例2.20 已知X?=-1011,分别求出变形补码取6位和8位时[X+]#。
解:[X-]=2?-1011=100 0000-00 1011=11 0101
[X+]#=2*-1011=100 000000-00 001011=11 110101
3.反码表示法
负数的补码可采用“各位取反,末位加1”的方法得到,如果仅各位取反而末位不加1,那
么就可得到负数的反码表示,因此负数反码等于在相应的补码表示中末位减1。
反码表示存在以下几方面的不足:0的表示不唯一;表数范围比补码少一个最小负数;
运算时必须考虑循环进位。因此,反码在计算机中很少被使用。
4.移码表示法
浮点数实际上是用两个定点数来表示的,用定点小数表示浮点数的尾数,用定点整数表
示浮点数的阶(即指数)。一般情况下,浮点数的阶用一种称之为“移码”的编码表示。通常,
将阶的编码表示称为阶码。
为什么要用移码表示阶呢?因为阶可以是正数,也可以是负数,当进行浮点数的加减运
算时,必须先“对阶”(即比较两个数的阶的大小并使之相等)。为简化比较操作,使操作过程
不涉及阶的符号,可以对每个阶都加上一个正的常数,称为偏置常数(bias),使所有阶都转
换为正整数,这样,在对浮点数的阶进行比较时,就是对两个正整数进行比较,因而可以直观
地将两个数按位从左到右进行比对,从而简化两个阶大小的比较过程。
假设用来表示阶E的移码的位数为n,则[E]。=偏置常数+E,通常,偏置常数取 2-1
或2"-1—1。
2.2整数的表示
整数的小数点隐含在数的最右边,故无须表示小数点,因而也被称为定点整数。整数可
分为无符号整数(unsigned integer)和带符号整数(signed integer)两种。
2.2.1无符号整数的表示
当一个编码的所有二进位都用来表示数值而没有符号位时,该编码表示的就是无符号
整数。此时,默认数的符号为正,所以无符号整数就是正整数或非负整数。
一般在全部是正数运算且不出现负值结果的场合下,使用无符号整数表示。例如,可用
无符号整数进行地址运算,或用来表示指针。通常把无符号整数简单地说成无符号数。
由于无符号整数省略了一位符号位,所以在字长相同的情况下,它能表示的最大数比带
符号整数所能表示的大,n位无符号整数可表示的数的范围为0~(2"-1)。例如,8位无符
号整数的形式为0000 0000B~1111 1111B,对应的表示范围为0~(2?-1),即最大数为
255,而8位带符号整数的最大数是127。
2.2.2带符号整数的表示
带符号整数也称为有符号整数,它必须用一个二进位来表示符号,虽然前面介绍的各种
二进制定点数编码表示(包括原码、补码、反码和移码)都可以用来表示带符号整数,但是补
码表示有其突出的优点,主要体现在以下几方面。
<!-- page: 50 -->
数据的机器级表示
(1)与原码和反码相比,数0的补码表示形式唯一。
(2)与原码和移码相比,补码运算系统是一种模运算系统,因而可用加法实现减法运
算,且符号位可以和数值位一起参加运算。
(3)与原码和反码相比,它比原码和反码多表示一个最小负数。
(4)与反码相比,不需要通过循环进位来调整结果。
现代计算机中带符号整数都用补码表示,故n位带符号整数可表示的数值范围为
-2*-1~(2"-(-1)。例如,8位带符号整数的表示范围为-128~+127。
2.2.3C语言中的整数类型
C语言中支持多种整数类型。无符号整数在C语言中对应 unsigned short、unsigned
int(unsigned)、unsigned long等类型,可在数的后面加一个u或U来表示无符号整数,例
如,12345U、0x2B3Cu等;带符号整数在C语言中对应short、int、long 等类型。C语言中允
许无符号整数和带符号整数之间的转换,转换后数的真值是将原二进制机器数按转换后的
数据类型重新解释得到。例如,考虑以下C代码: