计算机组成定点数的编码,2.1.1 定点数的表示
2.1 数据的表示
2.1.1 定点数的表示
1.原码表示法
在实际生活中,我们遇到的数据一般是十进制的、带正/负号的、带小数点的。但遗憾的是,截至目前,计算机能直接处理还只是由0和1组成的二进制数。因此,在计算机中,十进制数必须转换成二进制数(转换方法参见附录C),并且用0表示正号,用1表示负号。这样的符号“数字化”的二进制数称为机器数。相对而言,带+/-号的数称为真值。
为了简化设计与制造,计算机不直接表示小数点,而是默认小数点位于数值的前部或者后部,这样表示的数据称为定点数(Fixed Point Number)。小数点被默认位于数值前部的叫定点小数,被默认位于数值后部的叫定点整数。一般的计算机只选择实现一种定点数。
在早期采用定点小数的计算机里,大于1的数据必须先通过适当的比例因子转换成小于1的数据,并保证运算的中间结果也是小于1的,在输出结果时再将数据按比例放大、还原。采用定点小数的计算机是最节省硬件的。
在定点数的表示格式中,最高位(The Most Significant Bit,MSB)被当作符号位(Sign Bit)。也就是说,定点数的最高位为0,表示它是正数;为1,表示它是负数。
在机器实现中,定点数的小数点是不实现、不保存的。但是为了便于人们阅读时区别定点小数和定点整数,在定点数的书面表示中,一般在定点小数的符号位后加上一个“.”,在定点整数的符号位后加上一个“,”。
这样就得到了计算机中定点数最直观的表示方法:符号—绝对值表示法(The Sign-Magnitude Representation)。在我国,这种表示法称为原码表示法。例如,
X =+1011010B,[X]原=0, 1011010B;
Y=-1011010B,[Y]原=1, 1011010B;
Z=+0.1101010B,[Z]原=0. 1101010B;
K=-0.1101010B,[K]原=1. 1101010B。
事实上,一个二进制数据的具体原码表示依赖于机器的字长,机器字的最高位为符号位。
例如,Y=- 011010B,机器字长是8位时,[Y]原=1,1011010B;机器字长是16位时,[Y]原=1,000000001011010B。
【例2-1】 设机器字长为8位,X=-0101010B,Y=+1010101B,求[X]原 和[Y]原=?
答:[X]原=10101010B,[Y]原=01010101B。
【例2-2】 设机器字长为8位,X=0,求[X]原=?
答:对于零(0)而言,其原码中的符号位取0、取1都是可以的。
所以[0]原=10000000B或者[0]原=00000000B。
从例2-2可以看出:零(0)的原码表示有两种形式:正零和负零。这就给计算机实现“判断一个数是否等于零”(这是程序中一个常见的操作)带来麻烦。后面我们将会看到:这个问题可以通过引入补码(Complement)来解决。
由于需要拿出一位二进制数位来表示符号,所以原码表示的n位定点整数的表示范围是:+(2 n-1-1) ~-(2 n-1-1)。例如8位定点整数的表示范围是:-(27-1)~+(27-1),即-127~+127;16位定点整数的表示范围是:-(215-1)~+(215-1),即-32767~+32767。
原码表示的n位定点小数的表示范围是:-[1-2-(n-1) ]~+[1-2-(n-1) ]。
从理论上,n位二进制数共有2 n个码点(Pattern),能够表示2n个数据,但是原码表示的n位定点整数的表示范围是-(2 n-1-1)~+(2 n-1-1),只表示了2 n-1个数据,其原因就是零(0)的原码占去了两个码点。
由于n位二进制数需要拿出1位作为符号位,所以它能够表示的最大数的绝对值是(2n-1-1)。为了能够表示绝对值更大的数据,在数据都是正数的情况下,可以把符号位省略掉,n个二进制数位全部用来表示数据的数值。这样表示的整数称为无符号数(Unsigned Integer)。n位无符号数的表示范围是:0~+(2n-1)。例如8位无符号数的表示范围是:0~255,16位无符号数的表示范围是:0~65535。
从这个意义上说,定点数可分为带符号数和无符号数。原码表示法和下面将要介绍的补码、反码表示法都是针对带符号数的。
原码表示法简单明了,易于和真值转换,乘、除法运算的规则比较简单(详见2.2节),但是它最主要的缺点是加、减运算的实现比较复杂,即在执行用户指定加、减运算时,不能简单地直接进行加、减运算。它需要先判断两个操作数的符号及其绝对值的相对大小,然后再执行所需要的运算。例如,两数相加时,先比较符号位,若同号,则做加法,否则做减法。在做减法时,先比较两个数绝对值的相对大小,然后用绝对值大的数减去绝对值小的数,结果的符号取绝对值大的操作数符号。比如,用户指定(+5)-(-3),最终机器执行的是:5+3;用户指定(+5)+(-3),最终机器执行的是:5-3。
由此可见,采用原码表示法会导致加、减运算既复杂又费时,而且用户指定的加法运算有时却要使用减法器。那么,能否找到一个与负数等价的正数来代替该负数,然后用加法来代替减法呢?
可以!机器数采用补码表示就能实现这个愿望—ALU中只设加法器,只做加法操作。
2.补码表示法
引入补码表示法的目的是将加、减运算统一为加法运算,简化计算机的控制与实现。在介绍补码之前,我们先来介绍一下“模(Module)”的概念。
在我们日常使用的钟表中,假设当前时间是3点,而钟表快了2小时,它的时针已经指到了5点,就需要将时针调回到3点,即时针指向的数字5要变成3。
实现这个目的的方法有两个,一个是将时针逆时针拨两格(即真的减去2),另外一个是将时针顺时针拨10格(即加上10)。
为什么时针从5加上10却等于3呢?这是因为钟表上“小时数”都是以12为“模”,即“小时数”等于用12去除然后取余数。所以5+10=15 ( mod 12 )=3。
由此可见,在 “模为12”的意义下,“减去2”与“加上10”是等价的。我们称(-2)相对于“模为12”的补为:12-|-2|=10。
在计算机中,定点整数的补码是以2n为模。对于一个n位的定点整数X,如果X是一个正数,则它的补码与原码完全相同;如果X是一个负数,则它的补码就等于2n-|X|。
例如,在机器字长为8位的情况下,[+1]补=00000001B,[+127]补=01111111B,[-1]补=28-1=11111111B,[-127]补=28-127=10000001B。
值得注意的是:设机器字长为8位,超出部分自动丢失。[+0]补=00000000B,[-0]补=28-0=00000000B。可见,补码表示法中,零(0)的表示形式就统一了。
那么,原码中用于表示负零的那个码点10000000B不就空闲了吗?
不用担心,它在定点整数补码表示中被指定用来表示-2n- 1,即-128(n=8)或-32768 (n=16);在定点小数补码表示中被指定用来表示-1。
在实际应用中,补码往往是从原码转换来的。转换的口诀是:正数的补码就是它的原码;负数的补码是将其原码,除符号位外,每位取反(即0变成1,1变成0),然后在最低位(The Least Significant Bit,LSB)加1而得。
感兴趣的读者可以用数学的方法证明这个口诀。
【例2-3】 设机器字长为8位,X=- 46,求[X]补 =?
答:[X]原 = 10101110B。
除符号位外,对[X]原每位取反得到11010001B,在最低位加1得到11010010B。
所以,[X]补 =11010010B。
【例2-4】 设机器字长为16位,Y=-116,求[Y]补=?
答:[Y]原=1000 0000 0111 0100B。则 [Y]补=1111 1111 1000 1100B。
为简洁起见,在书写上述运算结果时,常采用十六进制表示(二进制转换成十六进制的方法参见附录C)。所以,[Y]补=1111 1111 1000 1100B = FF8CH。
观察上面两道例题的结果,一个负数的原码从它的低位算起,遇到第一个“1”时,原码与补码是相同的。超过这个“1”直至符号位之间的那段数位,原码与补码是相反的。这是一个很有价值的结论,可用于简化求补码电路的设计。
采用补码表示的n位定点整数的表示范围是:-2 n-1~+(2 n-1-1)。
例如,8位定点整数的补码表示范围是-27~+(27-1),即-128~+127;16位定点整数的补码表示范围是:-215~+(215-1),即-32768~+32767。
至于补码表示的n位定点小数的表示范围,请读者自行求解。
最后,需要补充说明的是:由原码求补码的口诀也同样适合于由补码求原码。因为一个数的原码和它的补码是互为补码的。
无论是寄存器还是内存单元都是定长的,如32位或16位。一个用8位补码表示的定点整数要存入长度更大的存储单元时,需要进行“符号位扩展”,即空出的高位用补码的最高位(符号位)填充。
类似的,ALU也只能对两个等长的操作数进行运算。当两个操作数不等长时,短的操作数在参与运算前,也要做“符号位扩展”。
【例2-5】 (2012年硕士研究生入学统一考试 计算机专业基础综合考试试题)
假定编译器规定int和short类型长度分别为32位和16位,执行下列C语言语句:
unsigned short x=65530;
unsigned int y=x;
得到y的机器数为_。
A. 0000 7FFAH B. 0000 FFFAH C. FFFF 7FFAH D. FFFF FFFAH
答:x(值为65530)的机器数为1111 1111 1111 1010B。
对于无符号数, unsigned short类型数据赋给unsigned int类型数据,不需要做符号位扩展。则y的机器数为0000 0000 0000 0000 1111 1111 1111 1010B=0000FFFAH。故选B。
3.反码表示法
反码通常作为由原码求补码或者由补码求原码的中间过渡。
对于正数,反码与原码和补码相同,直接在二进制数值前面加上符号位“0”即可。对于负数,反码就是将负号“-”替换成“1”然后将二进制数值逐位取反而得到。
在反码中,零有两个编码:定义为:[+0]反=000…00B,[-0]反=111…111B。
回顾求补码的过程可知:对于一个负数,求反码与求补码的差别仅在于“末位是否加1”。所以,有人称补码为“2的补码(Two抯 Complement)”,称反码为“1的补码(One抯 Complement)”。
4.移码表示法
原码、补码和反码,它们的一个共同特点是将符号作为最高位,与其数值部分一起编码。正号用“0”表示,负号用“1”表示。这就给比较不同符号的数据之间的相对大小,带来麻烦。例如,采用原码时,正数01010101B大于负数11010101B。但是机器认为“1”比“0”大,所以11010101B>01010101B。可见,机器比较的结果与真实情况不符。
如果给每一个二进制整数的真值加上一个常数2n(n为二进制真值的位数),使得正数的最高位变成“1”、负数的最高位变成“0”,那么,机器比较得到的两个数之间的相对大小就是其真实的相对大小。这样得到的编码称为“移码(Biased Representation)”。
移码的定义:[X]移=2n+X。其中X是n位二进制整数的真值,即-2n ≤X≤2n-1。
由于移码在编码中只是加上了一个常数,并没有改变数据之间原本的大小顺序,所以移码主要用于需要对定点整数(如下一节将要介绍的浮点数的阶码)进行大小比较的场合。
例如:X=0101011B,[X]移=27+X=10000000B + 0101011B= 10101011B;
Y=- 0101011B,[Y]移=27+Y=10000000B + (-0101011B) = 01010101B;
比较其大小,10101011B>01010101B,所以X>Y。
特别的,X=0000000B,[X]移=27+X=10000000B + 0000000B= 10000000B;
Y = -0000000B,[Y]移=27 + Y = 10000000B + (-0000000B) = 10000000B;
所以,[+0]移=[-0]移。在移码中,零(0)有唯一的编码。
部分8位定点整数的移码如表2-1所示。从表中可以看出,同一个真值的移码与其补码的差别仅仅是最高位相反。将补码的符号位取反,即可得到其对应真值的移码。
注意:移码表示仅仅是针对定点整数而言的,定点小数没有移码的定义。
总结
以上是生活随笔为你收集整理的计算机组成定点数的编码,2.1.1 定点数的表示的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 婚礼在家里举办还是在酒店里举办?[已扎口
- 下一篇: 计算机协会成立活动简报,“中国计算机学会