第6节 负数
数字系统使用固定信号的数量来表示二进制数。小型的简单的系统使用8比特总线就可以表示出 256个不同的二进制数,而在大型系统中可能使用16、32甚至64位总线。不管比特位的数量有多少,所有的系统都只有有限的连接线,存储单元以及处理单元来表示和处理数字数据。可用比特位的数量决定了在已知系统中可以表示出多少不同的数来。
数字电路中执行算术操作一般都要处理负数,所以必须要定义一种表示负数的方法。一个N比特的系统可以表示总共2N个数,所以可以使用一般的可用编码(2N/2)来表示正数,另一半表示负数。并用一个比特位来表示“符号位”,用于区别正数和负数-如果信号位是1,那么该数就是负的;如果符号位是0,那么该数就是正的。最好就是选用最高位(MSB)作为符号位,那么如果该位是0的时候(表示的是正数),在标定该数数量级的时候,就可以忽略该位。
在所有负数编码方式中,最经常使用的有两种方法:符号标定法和2的补码标定法。符号标定法就是将MSB位作为符号位,其余的比特位作为无符号数值。在一个8比特有符号数的系统中,“16”就表示为“00010000”,“-16”就表示为“10010000”。该系统表示法对我们来说可以很容易的表述,但是它对数字电路来说有个很大的缺点:如果从最低位到最高位变化是一个从0到2N的计数范围,那么最大的正数将出现在范围的一半,仅接着就是最小的负数。还有,最大的负数出现在范围的最后(即2N码),然后再一次的滚转表示,这是由于没有2N+1这种表示。因此,在0到2N的范围内,最大的负数直接邻接着最小的正数。由于这样的情况,一个简单的操作比如“2-3”,那么就需要向后计数两三次,并不能得到预期的结果-1,而是得到了系统中的最大负数。有一种更好的系统可以将最小的正数和负数放在计数范围内的邻接处,而这就是2的补码表示法所能做的。如小图所示的是8比特数的有符号法和2的补码法的数轮。
在2的补码编码方式中,MSB位仍然作为符号位-1表示负数,0表示正数。2的补码法用全0(包括第一个0)表示0值。其余的2NI-1个编码表示所有的非0数,包括正数和负数。由于2NI-1是一个奇数,那么我们用(2NI-1)/2来表示负数个数,用(2NI-1)/2-1来表示正数个数(0已经作为了一个正数)。换句话说,我们可以表述为非0的负数要比正数多一个,最大负数的绝对值也比最大正数的绝对值大1。
2的补码的缺点就是不能直观的看出负数值(比如能看出“11110100”是-12么?)。有一简单的算法可以将正数写成2的补码方式,绝对值不变,也可以将2的补码方式的负数转换为同绝对值的正数。算法如下例子所示,将所有需要转换的比特位翻转,然后在最低位上加1。该算法可以用上面的2的补码数轮来直观显示,翻转所有比特位就相当于以0为轴进行轴对称的映射,加1就相当于补偿了负数码大于正数码的那个1。
数字电路中执行算术操作一般都要处理负数,所以必须要定义一种表示负数的方法。一个N比特的系统可以表示总共2N个数,所以可以使用一般的可用编码(2N/2)来表示正数,另一半表示负数。并用一个比特位来表示“符号位”,用于区别正数和负数-如果信号位是1,那么该数就是负的;如果符号位是0,那么该数就是正的。最好就是选用最高位(MSB)作为符号位,那么如果该位是0的时候(表示的是正数),在标定该数数量级的时候,就可以忽略该位。
在所有负数编码方式中,最经常使用的有两种方法:符号标定法和2的补码标定法。符号标定法就是将MSB位作为符号位,其余的比特位作为无符号数值。在一个8比特有符号数的系统中,“16”就表示为“00010000”,“-16”就表示为“10010000”。该系统表示法对我们来说可以很容易的表述,但是它对数字电路来说有个很大的缺点:如果从最低位到最高位变化是一个从0到2N的计数范围,那么最大的正数将出现在范围的一半,仅接着就是最小的负数。还有,最大的负数出现在范围的最后(即2N码),然后再一次的滚转表示,这是由于没有2N+1这种表示。因此,在0到2N的范围内,最大的负数直接邻接着最小的正数。由于这样的情况,一个简单的操作比如“2-3”,那么就需要向后计数两三次,并不能得到预期的结果-1,而是得到了系统中的最大负数。有一种更好的系统可以将最小的正数和负数放在计数范围内的邻接处,而这就是2的补码表示法所能做的。如小图所示的是8比特数的有符号法和2的补码法的数轮。

在2的补码编码方式中,MSB位仍然作为符号位-1表示负数,0表示正数。2的补码法用全0(包括第一个0)表示0值。其余的2NI-1个编码表示所有的非0数,包括正数和负数。由于2NI-1是一个奇数,那么我们用(2NI-1)/2来表示负数个数,用(2NI-1)/2-1来表示正数个数(0已经作为了一个正数)。换句话说,我们可以表述为非0的负数要比正数多一个,最大负数的绝对值也比最大正数的绝对值大1。
2的补码的缺点就是不能直观的看出负数值(比如能看出“11110100”是-12么?)。有一简单的算法可以将正数写成2的补码方式,绝对值不变,也可以将2的补码方式的负数转换为同绝对值的正数。算法如下例子所示,将所有需要转换的比特位翻转,然后在最低位上加1。该算法可以用上面的2的补码数轮来直观显示,翻转所有比特位就相当于以0为轴进行轴对称的映射,加1就相当于补偿了负数码大于正数码的那个1。



