1. 计算机中的数
计算机中的数可分为两类:一类是数值性的数,另一类是非数值性的数。数值性的数主要用于计算。非数值性的数主要用于信息处理。数值性的数表示的是事物的数值或数量,非数值性的数表示的是事物的名称、属性、存在位置、形体特征等。
数值性的数有正数和负数,为了在计算机中区分正、负,人们用 0 代表正,用 1 代表负。
数除了有正、负之外,还有整数、小数之分。在计算机中为表示这些数规定了两种形式的数:一种是定点数,另一种是浮点数。其中,定点数又分为定点小数和定点整数。在计算机中不论表示定点数还是表示浮点数都受着空间,即表示位数的限制,当一个数的位数过多,或者数过大、过小都有可能产生表示不了的问题。围绕着这个问题又提出了以下概念。
① 数的界:把在给定的表示空间里数的最大值和最小值分别称作数的上界和下界,上、下界之间称作数的表示范围。
② 溢出:当数过大,大到超出数的上界所产生的现象称为上溢溢出;当数过小,小到超出数的下界所产生的现象称为下溢溢出。
③ 误差及精度:当数的位数的位数超出表示空间所划定的位数,因截尾而产生的与原数的差别称为误差。精度,即精确度,它是度量误差的尺度。
理解上述概念很重要,需要分清的是,数在给定空间表示不下时并不一定会产生溢出,而溢出则肯定是数在给定空间表示不下。
2. 数的编码
数在计算机中为了进行运算、比较大小等需要,必须进行编码。所谓编码是指如何用 0 、 1 这两个码来表示一个数。由于构成数的成分有正号、负号、小数点、指数等,所以就带来了这些成分的处理问题。
在计算机中数的常用编码有原码、补码、反码、移码、变形补码等。不管是那种编码,无不是根据需要而提出的。在理解每种编码的定义、特点的基础上,掌握编码之间的关系及相互转换是必备的基础。
原码与真值的关系简单、直观;补码可以把减法变为加法,从而使加、减、乘、除都通过加法操作来实现;反码是原码变补码的过渡码;移码与真值存在着线性关系,用来比较数的大小较方便,常用作浮点数的阶码;变形补码可以用来进行加法运算,并在运算过程中判断是否产生了溢出。
3. 编码之间的转换
(1)以原码为基础的转换
由于原码与真值的关系简单,所以以原码为基准可以建立原码、反码、补码之间的转换关系,如表 1-1 所示。
(2)以补码为基础的转换
若以补码为基准,可建立补码、移码及变形补码之间的转换关系,如表 1-2 所示。
根据上述转换法则,在实施转换中首先要确定被转换对象的属性,即正、负,然后再进行转换。容易产生错误的补码和移码。这是因为从形式上看补码和移码距离真值差别较大。例如, 10000000 ,如果它是 8 位整数的补码,其真值为 ;如果它是 8 位小数的补码(小数点隐含在符号位之后),其值为 –1 。再如, 00000001 ,如果它是 8 位整数移码,变为补码后 10000001 ,其值为 ;如果它是 8 位小数移码,变为补码后 10000001 ,其值为 ,相当于二进制的 。
4. 数的真值及范围
(1)定点小数的真值及范围
小数点隐含在符号位及尾数的最高位之间,不占位数。
在计算机中,定点小数的形式通常定义如下:
(2)定点整数的真值及范围
小数点不占位数,隐含在尾数最低位之后。
按照数的表示形式,对定点整数在不同编码下所代表的真值及在给定空间下数的表示范围进行归纳,如表 1-4 所示。
(3)浮点数的真值及范围
浮点数的表示范围为:
为阶码连同阶符号的位数, 为连同符号的尾数位数。
1.2.2 难点分析
第一,数要在计算机中表示、必须使用编码,这是因为在计算机中只能表示 0 和 1,而数的正号、负号在表述中一旦用 0、1 代替后,数的表示形态与量值就发生了变化,把表示在计算机中的数称为机器数,而数的原来的值称为真值。
第二,在计算机中,真值已面目全非,要想把握真值就需要建立编码与真值的关系。
第三,编码本身是在特定空间出现的,所以讨论编码与真值的关系就需要针对定点小数、定点整数及浮点数等这些特定的空间来讨论,分析它们的大小、变化及特点。
第四,引出不同的编码还有一个重要的方面,就是便于运算及操作。
1. 原码的由来与特点
(1)定点小数的原码
①1、-1 因值过大、过小均不能表示成小数原码。因此,可以推断当进行定点小数运算时,若结果值越界也将会产生上溢或下溢溢出。
②整数的原码与真值相同,即有 。
③负数的原码中,因除了一个其值为1的符号,而原码小数点后的值,即尾数证号等于真值的绝对值,因此负数原码与真值的关系为:
④参照上述结果可以得出表述原码与真值关系的表达式,称为原码表达式:
⑤值得注意的是,0.0 和 -0.0 其原码截然不同。这说明真值 0 的原码是不唯一的。
(2)定点整数的原码
①128、-128 因值过大、过小,均不能用 8 位原码表示。这说明 8 位长的原码有相应的上、下界。在运算中如出现越界的结果,也将会产生上溢或下溢溢出。
②正数的原码与真值相同,即有。
③负数的原码中符号 1 相当于 = 128,由于 = 8,所以 。负数原码尾数正好等于真值的绝对值。根据这种关系,可以把负整数原码与真值的关系表示为:
④综合正、负数原码与真值的关系,可以把表达原码与真值关系的原码表达式写为以下形式:
⑤整数 0 的原码也有截然不同的两种形式,即 0 的原码不唯一。
(3)原码小结
原码是真值符号数值化与真值绝对值依次排列所构成的编码。由于正号用 0 表示,所以正数的原码与真值相同。负数的符号用 1 表示,所以由真值变为原码时,出现了一个高位 1。对于定点小数来说,高位 1 其值为 1;对于定点整数来说,高位 1 其值为 。0 的原码无论是小数形式还是整数形式都是不唯一的。
2. 补码的提出及使用
由于在运算中使用原码不太方便,如在加、减运算中需要判断正、负号等,于是人们又提出了一种方便运算的编码即补码。
(1)记数系统的模
记数系统的容量称为该系统的模。任何一个记数系统都有其固有的容量,即模。
(2)互补与补码
从记数系统的模可以导出互补关系,进而引出补码。
①正数的补数是其本身,负数的补数可由模加该数求出。
②在该系统中二数相减可以转换为二数相加。
③由于模是该系统的临界值,它始终处在系统之外,所以在计算中产生了大于或等于(相当于时钟时针旋转一个或一个以上的周期)模的值时,模会自然消失。
④将模、互补、补数、模在运算中自然消失等概念推广到二进制记数系统,就产生了补码及补码运算。
(3)定点小数的补码
将 n 位的定点小数空间视为一个记数系统,小数点隐含在最高位之后,说明在该记数系统中只有一位整数空间,所以空间的模为 2。在该空间内对于任意小数 x 来说,若 x 为正,它的补码为其本身;若 x 为负,它的补码由模加 x 求得。于是可以写出下列补码表达式:
根据该式,当已知真值时,可以求其补码;当已知补码时,可以求其对应的真值。
(4)定点整数的补码
n 位的定点整数空间,其模为 。由于正数的补码是其本身,所以定点整数真值 x 与补码的关系可表示为下式:
(5)补码的运算
根据补码的表达式可以进行补码与真值之间的转换,利用补码可以把减法运算转换为求补码之和。值得注意的是,无论是做加法还是做减法都可以用“求补码之和”来实现。但是,用补码求和所得出的结果仍为一个补码。当需要真值来表达计算结果时,还需要将结果的补码返回真值。
(6)补码小结
补码具有以下特点:
①零的补码是唯一的全 0。它不像原码零有正零和负零两种形式。
②可以拓宽数的下界。它比原码表示数的范围要大,这是因为在数的存储空间长度给定后,原码的零占两个位置,而补码的零只占一个位置。因此补码可以多表示一个数。
③使用补码可以把减法变为加法,即把两数相减变为对两数补码求和。利用补码的这一特点可以把加、减、乘(连加)、除(连减)统一用加法来实现。应该说,这是补码的一大贡献。早年的计算机就是基于补码的这一特点,在硬件上把运算器设计为以加法器为中心的运算部件。直到现在计算机中的数值性数据均存为补码形式。
④补码优点很多,但从应用上还有待完善。例如,补码虽然可以把减法变为加法,但求负数补码时仍然摆脱不了使用减法。为完善补码的使用体系,人们又提出了另一种编码,这就是反码。
3. 反码的出现及作用
反码是这样定义的:正数的反码是其本身,负数的反码是原码的符号位不动,尾数逐为求反(即 0 变 1,1 变 0)而得出的一种编码。在计算机中利用反向器实现 0 变 1,1 变 0 是十分容易的。根据反码与原码的关系,可以导出反码的表达式。因为正数的反码与真值相同,所以也与原码相同,因此,只需要讨论负数的反码。
(1)定点小数的反码
定点小数反码的表达式为:
(2)定点整数的反码
定点整数反码的表达式为:
(3)反码小结
①反码的零有两种形式:正零——00000000(n = 8);负零——11111111(n = 8)。
②反码是原码变补码的中间过渡码。正数的反码既同原码也同补码。负数的反码是在原码的基础上符号位不动,尾数逐位求反(即 0 变 1,1 变 0)而形成的编码。反码和补码的关系可以从两种编码的表达式得出。正数的反码与补码相同,负数的反码加(低位)1 即为补码(加 1 时符号位不动)。同理,补码减去一个低位 1(即补码表达式 减去 1)就变成了反码(表达式为 )。根据这种关系就形成了原码变补码的法则“求反加 1 ”。
③定义了反码后,求负数的补码就可以通过原码,也可以借助反码,再也不需要只依赖减法运算了。因此,可以说反码的出现解决了求补码用减法的困惑,并把编码之间的转换脱离了使用真值的不便。
④反码作为独立的一种编码,可以把它看成是“对 1 的补码”。以负数反码为例,在表达式 中, 是对 1 补码的模,显然该值为全 1。于是将反码(称为对1的补码)的表达式写为 ,使用该式可以有模和真值求出反码。
4. 变形补码的定义与用途
一种完善补码运算的工具,即变形补码。
(1)变形补码的提出
为了能够判断运算是否正常,鉴别运算中的溢出及模自然消失,判定计算结果是否合理,人们又规定了一种新的编码,这就是变形补码。使用变形补码进行补码求和可以判定结果为正还是为负,指出运算中是否发生了溢出,并能分辨出是上溢溢出还是下溢溢出。
变形补码是在补码的基础上,多加一个相同的符号而形成的一种编码。
(2)变形补码对溢出的判定
使用补码求和,数的符号也参与了运算,使用变形补码求和,有两个符号都参与运算。两个符号位可以记录4中状态:00,01,10,11,这 4 种状态可以说明 4 种运算状况,如表 1-11 所示。
5. 移码的定义与特长
(1)移码的定义
移码也叫增码,是由补码改变符号而得到的一种编码。当补码的符号为0时,将 0 变为 1;当补码的符号为 1 时,将 1 变为 0,这样变换所形成的编码为移码。移码与补码的唯一差别是相差一个符号位。因此,改变移码的符号也可以形成补码。
由于移码与补码相差一个符号位,所以分析移码可以以补码为基础,找出因符号改变所引起的量值变化就可以得出移码的表达式。
(2)定点小数移码
当符号由 0 变 1 时,其值增加为 1;当符号由 1 变 0 时,其值减少为 1。根据这个变化,正数补码变移码时,在补码上加 1;负数补码变移码时,在补码上减 1;因此,移码与补码的关系可以表示为:
将定点小数补码表达式代入上式,便得出定点小数移码表达式:
从表达式可以看出,不论是正小数还是负小数,移码表达式是相同的,而移码与真值的关系为 ,这说明移码实际上是在真值 x 的基础上平移了一个常数 1,移码与真值是一种线性增加的关系。因此,将其称为移码或增码是很贴切的。
(3)定点整数移码
当符号由 0 变 1 时,其值增加一个 ;当符号由 1 变 0 时,其值减少一个 。根据这个量值的变化,当正数的补码变移码时,将增加一个 ;当负数的补码变移码时,将减少一个 。因此,移码与补码的关系可表示为:
从表达式可以看出,整数的移码与真值的关系也是平移或增加一个常数()的线性关系。
(4)移码小结
①由于移码是补码变号而来,而零的补码是唯一的全 0,所以零的移码是唯一的100…000。
②由于移码与真值是一种线性(平移常数)关系,所以移码在计算机中可以代表真值进行数的比较。在这一点上其他编码是不具备的。
6. 数的形式与真值
1)术语及其含义
讨论数的形式与真值的关系,需要理解下列术语。
①单元:数的一个单位的表示(或存储)空间通常被称作一个单元。单元的大小是根据需要和可能划分的。比如,8位、16位、32位、64位等都可以作为一个单元。
②字:一个单元中的数称为一个字。
③字长:一个字所具有的二进制位数称为字长。字长也可以针对单元的容量来称谓,即单元的长度称为字长。由于单元长度是以二进制位的位数来度量的,所以字长也可以说成是一个单元能容纳的二进制位数。
④真值与机器数:数的十进制或二进制的实际值称为真值。而表示在计算机单元中的数称为机器数。
⑤机器无穷大数:在计算机中超越单元上界的数统称为机器无穷大数。显然,机器无穷大数是一个相对值。例如,字长8位的单元最大(即上界)可容纳 127,若在运算中产生了大于 127 的值,对 8 位字长的单元来说就成了机器无穷大数。
⑥机器无穷小数:在计算机中超越单元下界的数统称为机器无穷小数。机器无穷小数也是相对单元容量而言的。例如,字长 8 位的定点整数单元,可以表示的值(用补码)为 –128,若在运算中产生了小于 –128 的值,对 8 位定点整数单元来说就是机器无穷小数。机器无穷小数也常被人们称为机器零。
⑦溢出:溢出所描写的是在运算中出现了大于单元上界或小于单元下界而出现的存储空间容纳不了的现象。若出现超越上界的溢出称为上溢溢出;若出现超越下界的溢出称为下溢溢出。溢出会在状态字中出现标志位置 1 或 0,同时产生中断并转中断处理程序,输出有关信息。
2)数的误差及越界
由于受着字长的限制,在运算中会出现计算结果的位数多于字长所给定位数的情况。若出现在定点小数中,则会因计算结果被截尾而带生误差;若出现在定点整数中,则会发生溢出。
截尾所产生的误差称为截断误差,计算误差的方法有下列两种:
①绝对误差,代表存入单元之前与之后的数量差,用 A 表示如下:
式中,S 为存入单元之前的数, 为存入单元之后的数。
② 相对误差用下式表示:
3)浮点数与真值的关系
(1)单元的位数分配与真值的关系
由于浮点数的阶码是整数,尾数是小于 1 的小数,所以浮点数的表示真值的范围取决于阶码所占有的位数。
为了扩大浮点数的表示范围,在一个单元中可以为阶码划分更多的位数。但是在字长恒定的情况下,阶码位数占多了,必然使得尾数的位数减少,这又将给浮点数带来什么影响呢?接下来就此问题进行分析。
由于浮点数的尾数是定点小数形式,尾数位数减少会使得容纳小数的位数减少,这将会影响浮点数的(表示)误差,即影响浮点数的(表示)精度。因此,阶码和尾数位数划分,既要满足数的表示范围,又要保证数的表示精度。
一种即不影响数的表示精度又能扩大数的表示范围的作法是将隐含的底 2 改为 4、8、16、…,这样可以使浮点数表示范围由 2 的幂变为 4(或8、16)的幂。设想这样做对浮点数的形式没有任何影响,却把浮点数的表示范围扩大了 2 的幂倍。
(2)浮点规格化数
任意一个二进制数,都可以表示为指数形式,把这种指数形式的数按规定放在浮点数单元,就成了浮点数。
由于数的任意存放,就出现了单位尾数位数不够而真值被截断的情况。为了保证真值的精度,必须使用一种统一的规范形式,这种形式就称为浮点规格化数。
浮点规格化数要求尾数中能够的高位 1 必须在小数点后的第一位,由于小数点是隐含的,实际上是尾数的符号位之后必须紧跟着 1。
(3)浮点数的移位
浮点数的尾数每向左移一位,其阶减 1,每向右移一位,其阶加 1,均不改变浮点数的值。但需要特别提醒的是,当负数补码右移时,右移出现的空位必须补 1 才能保证右移后仍为补码。
参考文献:
[1]刘克武.软件设计师考试科目1:计算机与软件工程知识——考点解析及模拟训练[M].北京:清华大学出版社,2005.1.