1.3 带符号数的代码表示
1.3.1 原码及其运算
日常书写时在数值前面用“+”号表示正数,用“-”号表示负数,这种带符号二进制数称为真值。在计算机处理时,必须将“+”和“-”转换为数码,符号数码化的数称为机器数。一般将符号位放在最高位,用“0”表示符号为“+”,用“1”表示符号为“-”。根据数值位的表示方法不同,有3种类型:原码、反码和补码。
原码是指符号位用0表示正,1表示负;数值位与真值一样,保持不变。
如:已知X1=+1101,X2=-1101,则[X1]原=01101,[X2]原=11101。
已知X3=+0.1011,X4=-0.1011,则[X3]原=0.1011,[X4]原=1.1011。
可以用下面的公式来将真值转换为原码(含一位符号位,共n位)。
整数:
表示范围:-127~+127(8位整数时)。
注意整数“0”的原码有两种形式,即[+0]原=00…0和[-0]原=10…0。
纯小数:
纯小数“0.0”的原码也有两种形式。
原码的优点是容易理解,它和代数中的正负数的表示方法很接近。但原码的缺点是“0”的表示有两种;原码的运算规则复杂,若X=Y+Z,但(X)原≠(Y)原+(Z)原。
例如(+1000)2=(+1011)2+(-0011)2,但是(+1011)原=01011,(-0011)原=10011,它们直接相加不等于(+1000)2的原码(01000)。为了使结果正确,原码的加法规则为:
1)判断被加数和加数的符号是同号还是异号。
2)同号时,做加法,结果的符号就是被加数的符号。
3)异号时,先比较被加数和加数的数值(绝对值)的大小,然后由大值减去小值,结果的符号取大值的符号。
由于原码的运算规则复杂,为了简化机器数的运算,需要寻找其他表示负数的方法。
1.3.2 反码及其运算
反码的符号位用“0”表示正,“1”表示负;正数反码的数值位和真值的数值位相同,而负数反码的数值位是真值的按位变反。
可以用下面的公式来将真值转换为反码(含一位符号位,共n位)。
整数:
表示范围:-127~+127(8位整数时)。
注意整数“0”的反码有两种形式,即[+0]反=00…0和[-0]反=11…1。
纯小数:
同理,纯小数“0.0”的反码也有两种形式。
采用反码进行加、减运算时,无论进行两数相加还是两数相减,均可通过加法实现。
[X1+X2]反=[X1]反+[X2]反
[X1-X2]反=[X1]反+[-X2]反
运算时符号位和数值位一起参加运算。当符号位有进位产生时,应将进位加到运算结果的最低位,才能得到最后结果,称为“循环相加”(或“循环进位”)。
【例1-6】已知X1=+0.1110,X2=+0.0101,求X1-X2。
解:X1-X2可通过反码相加实现。运算如下。
[X1-X2]反=[X1]反+[-X2]反=0.1110+1.1010
=10.1000(符号位上有进位)
=0.1001
在反码中,从[X]反求[-X]反的方法是符号位连同数值位一起0变1,1变0。
例如,[X]反为0.0101,则[-X]反为1.1010。
1.3.3 补码及其运算
补码是符号位用“0”表示正,“1”表示负;正数补码的数值位和真值相同,负数补码的数值位是真值的按位变反,再最低位加1。
如:X1=+1101,X2=-1101,则[X1]补=01101,[X2]补=10011。
X3=+0.1011,X4=-0.1011,则[X3]补=0.1011,[X4]补=1.0101。
可以用下面的公式来将真值转换为补码(含一位符号位,共n位)。
整数:
表示范围:-128~+127(8位整数时),补码10000000表示-128(-27)。
整数“0”的补码只有一种形式,即00…0。
纯小数:
采用补码进行加、减运算时,无论进行两数相加还是两数相减,均可通过加法实现。
[X1+X2]补=[X1]补+[X2]补
[X1-X2]补=[X1]补+[-X2]补
运算时符号位和数值位一起参加运算,不必处理符号位上的进位(即丢弃符号位上的进位)。
【例1-7】已知X1=+0.1110,X2=+0.0101,求X1-X2。
解:X1-X2可通过补码相加实现。运算如下。
[X1-X2]补=[X1]补+[-X2]补=0.1110+1.1011
=10.1001(丢弃符号位上的进位)
=0.1001
当真值用补码表示时,补码加法的规律和无符号数的加法规律完全一样,因此简化了加法器的设计。
从[X]补求[-X]补的方法是符号位连同数值位一起变反,尾数再加1。
【例1-8】已知X=+100 1001,求[X]补和[-X]补。
解:[X]补=0100 1001,[-X]补=1011 0110+1=1011 0111
1.3.4 符号位扩展
在实际工作中,有时会遇到两个不同位长的数的运算,如将8位与16位机器数相加,为确保运算正确,两者在运算时应将符号位对齐。例如将8位与16位机器数相加,则应将8位数扩展为16位数,一种容易理解的方法是先根据机器数得到真值,在真值前面填8个0,然后转变为机器数。更快的方法是,对于反码、补码,扩展的数据位的值和原来符号位的值是一样的。