首页 理论教育 带符号数的表示方法-微型计算机原理

带符号数的表示方法-微型计算机原理

时间:2023-11-03 理论教育 版权反馈
【摘要】:而根据编码方式的不同,带符号数的表示方法又可以分成原码、反码和补码三种。

带符号数的表示方法-微型计算机原理

在上面我们讨论的二进制数中,没有涉及数的符号问题,而在实际应用中,数不可避免的要有正负,那么在计算机里面如何表示数的正负呢?

如果我们在计算机里用在数字前面加上正号或负号的方式来表示数的正负,这样将不可避免地要引入新的符号,而使计算机无法表示它们(因为计算机的绝大多数器件只有两种状态,也就是说,它们只能表示和运算两个不同的数字符号)。这个问题只能用编码的形式来解决。好在数字只有正和负两种状态,而二进制数制本身就包含有两个不同的数字符号,那么用一位二进制数字就足以表示数字的正负了。在计算机里面,通常规定二进制数据的最高位为符号位,以该位为0表示数为正数,以该位为1表示数为负数。这样,对于一个32位的二进制数,D31为符号位,D30~D0为数字位。而根据编码方式的不同,带符号数的表示方法又可以分成原码、反码和补码三种。用原码、反码和补码表示的数被称作机器数,对应的数学值则称为真值。

1.原码

原码是带符号数三种表示法中最直观的一种。其表示规则是:最高位为符号位,用0表示正数,1表示负数,数字位直接表示真值的绝对值。例如,用8位原码表示的二进制数:[+100]=01100100,[-100]=11100100。

用公式来表示,就是:

若X≥+0,则[X]=X,

若X≤-0,则[X]=2n-1-X,其中n为二进制数的位数。

原码表示法直观,与真值的转换方便。其表示的真值范围是-(2n-1-1)~(2n-1-1),其中n为二进制数的位数。例如n=8时的真值范围为-127~127。

但是如果两个异号数相加或同号数相减就必须使用减法操作,对于运算器的设计不利。同时原码的真值0对应于两个不同的机器数00000000(+0)和10000000(-0),也给运算器的设计增添了不少麻烦。为了简化运算器的设计,将减法运算转换为加法运算,引入了反码和补码。

2.反码

和原码一样,反码也以最高位做符号位,0表示正数,1表示负数。反码的正数表示和原码的正数表示是相同的,只是在表示负数的时候,其数字为是绝对值的按位取反。例如8位反码表示的二进制数:

[+100]=01100100,[-100]=10011011。

用公式来表示,就是:

若X≥+0,则[X]=X,

若X≤-0,则[X]=2n-1+X,其中n为二进制数的位数。

反码表示的真值范围和原码相同,也是-(2n-1-1)~(2n-1-1),其0也对应于两个不同的机器数:00000000(+0)和11111111(-0)。由于反码表示对计算机的结构有特殊的要求,所以现在也很少采用。

3.补码

在当前的计算机系统中,被广泛使用的带符号数表示法是补码表示法。补码的概念来自于数学中的按模取补,其基本思想是把负数用其以2n为模的补数来表示,以使正负数的加减法运算得到统一,简化运算器的设计。

我们首先来看这样一个例子,对于8位二进制数加法:

01100100+11111101=(1)01100001 ……高位的1由于超过表示范围而被舍弃

我们可以将这个运算结果解释为:100+253=353,同时353=97mod256,由于最高位的1超出了表示范围而被舍弃,结果01100001=97。(www.xing528.com)

换一种思路,我们也可以对上面的二进制加法运算给出另外一种解释:100+(?)=97。也就是说用253(即-3的互补数)的二进制原码11111101来表示带符号数-3,从而得到100+(-3)=97的正确结果。

这就是补码表示法的基本思想,对于正数,直接用其原码来表示,对于负数,用其模2n的互补数的二进制原码来表示,借助于丢弃超过表示范围的二进制数位,从而将正负数的加减法运算规则加以统一,达到简化运算器设计的目的。

用公式来表达,就是:

若X≥+0,则[X]=X,

若X≤-0,则[X]=2n+X,其中n为二进制数的位数。

从这个公式,我们可以得到求一个数补码的方法:对于正数,其补码为原正数不变(原码、反码也是一样的);对于负数,补码等于反码加1,就是说,把负数的原码按位取反并在最低位上加一作为负数补码的数字位,再加上最高位上用1表示的符号位,就得到了负数的补码表示。例如:

[+3]=00000011,

[-3]=[-3]+1=11111100+l=11111101,

[+0]=00000000,

[-0]=[-0]+1=11111111+1=(1)00000000。 ……高位的l被舍弃

需要注意的是,和原码、反码有[+0]和[-0]两个表示不同,补码中0只有一种表示方法,即00000000。这种特性对于简化运算器的设计也非常有利。

由于补码中0不再像原码、反码中的0那样占据两个不同的码位,补码所表示的真值范围也和原码、反码不同,对于n位二进制补码,其所能表示的真值范围是-2n-1~2n-1。以8位补码表示为例,其能够表示的真值范围是-128~+127,用10000000表示的-128是原码和反码都无法表示的。(想一下,为什么10000000表示的是-128而不是+128?)

对于采用补码方式表示的二进制数,其真值可以按照下面的方法进行计算:当符号位为0时,真值为正数,其余位即为此数的二进制值;当符号位为1时,真值为负数,将其余位按位取反并在最低位上加一得到真值的绝对值。

依赖于互补数的数学特性,补码实现了带符号二进制数加减法的统一,减法可以通过加上其相反数的方式来实现,即[X±Y]=[X]+[±Y]。(例如[12-3]=[9]=00001001=(1)00001001=00001100+11111101=[12]+[-3]

4.补码运算中的溢出问题

考虑在8位二进制补码表示下进行如下运算:

[100]+[100]=01100100+01100100=11001000=?

从真值来看,100+100的和应当是200,而补码相加的结果11001000按照补码的规则计算得到的真值是-56,也就是说,100+100得到的结果变成了-56,两个正数的和变成了负数。究其原因,8位二进制补码的表示的真值范围是-128~+127,100+100的和200明显不在这个范围之内,就是说100+100的结果已经超出了8位二进制补码的表示能力,这就是通常所称的“溢出”。

那么,如何判定一次运算的结果是否发生了溢出呢?简单来看,一次计算结果的溢出可以用参与加法运算的两个加数和结果的符号关系来进行判断:当且仅当一次计算的两个加数同号且与加法的结果(和)异号的时候,这次加法运算发生溢出。这种判定方法比较直观,但对于计算机上的实现比较麻烦,因此我们经常用另外一种方式来判断加法运算的溢出:假如令参与加法运算的两个二进制补码的最高位加法的进位为Cn,次高位加法的进位为Cn-1,则这次加法的溢出判定O=CnXORCn-1。当O=1时,代表加法操作发生了溢出。(为什么?请读者自行证明)

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈