目录
ID:HL_5461
引言
在计算机计算两数相加减时常常会有加得的数字超出类型所能表示的范围的情况。比如一个四位的二进制数,所能表示的范围为0~15,当我们计算13+13时,结果为26,写成二进制为11000,显然超过了四位的表示范围,这就是溢出。
下面我将介绍三种判断溢出的方法,但在说方法之前,我们先得了解两件事。
第一件事:只有“正数+正数”以及“负数+负数”这两种情况才会造成溢出。
桥豆麻袋,我知道很多人或许会说,还有正数-负数,负数-正数这些情况呢!但是呢,以和
为例:
,而
,因此,所有的会溢出的情况都可以写成“正数+正数”以及“负数+负数”这两种情况。当然其实还有一个重要原因,就是由于减法电路比较贵,所以即使是减法,计算机也会像我们前面举例一样转化为加法计算,所以以下我们判断溢出的方法都是围绕“正数+正数”以及“负数+负数”这两种情况进行的。其中,正数相加溢出称为上溢,负数相加溢出称为下溢。
第二件事:计算机在运算时都是使用补码进行运算的。
如A+B,计算机会先将A和B转变为其补码然后相加,其相加结果也是补码,然后将结果的补码再转回其原码,就是我们想要的值了。
一、单符号位逻辑表达式判断
1.结论
先说结论:
对于式子
,有
其中,
为
的符号位,
为
的符号位,
为
的符号位。当
表示无溢出,
表示有溢出。
举个栗子:
两个四位(含一位符号位)的二进制数,A和B,A=4,B=5,[A+B]补 = 0100+0101 = 1001。所以,,
,
。
即对a取反,所以
,
,
。ABC表示A与B与C,所以
,
。+为或,所以
,有溢出。
2.解释
正如前面所说的,我们围绕“正数+正数”以及“负数+负数”,即上溢和下溢这两种情况进行讨论,一种情况溢出则表示有溢出,所以我们可以有一个大致的轮廓:V表示是否溢出,那么V肯定等于(什么)或(什么),即,我们接下来只需考虑()里面是什么就可以啦。
还是以A和B为例,A和B两个四位(含一位符号位)的二进制数,A+B=S。
(1)上溢
当A、B全为正数,那么A和B补码应该为0xxx形式,对于俩正数相加,如果没有溢出,S也应该为正数,即S的补码为0xxx形式。如果溢出,如A=4,B=5,那么此时S=1001,注意,这里S为补码且有一位符号位,所以这里的S并不是9。应该现将其转化为原码,即1111,然后看值,S=-15,是一个负数。
所以,正数相加溢出的标志是结果符号位为1。
由此,我们可以很容易得出正数溢出的逻辑表达式为。即,当A符号位为0,且B符号位为0,且S符号位为1时溢出了。
(2)下溢
当A、B全为负数,那么A和B补码应该为1xxx形式,对于俩正数相加,如果没有溢出,S也应该为负数,即S的补码为1xxx形式。如果溢出,如A=-4,B=-5,A补=1100,B补=1011,此时S=10111,注意,因为S是一个四位的二进制数,所以将最高位舍去,即,S=0111。因为符号位为0,表示S是一个正数,正数原补码相同,将S转化为原码还是0111,S=11,是一个正数。
所以,负数相加溢出的标志是结果符号位为0。
由此,我们可以很容易得出负数溢出的逻辑表达式为。即,当A符号位为1,且B符号位为1,且S符号位为0时溢出了。
最后两式相或,得到我们前面提到的溢出判断的逻辑表达式。
二、单符号位进位情况判断
1.结论
符号位的进位 最高数值位的进位 上溢 0 1 下溢 1 0 溢出判断:
举个栗子:
两个四位(含一位符号位)的二进制数,A和B,A=4,B=5,[A+B]补 = 0100+0101 = 1001。最高数值位的进位,符号位的进位
,
和
相异或为1,所以溢出。
2.解释
还是以A和B为例,A和B两个四位(含一位符号位)的二进制数,A+B=S。
(1)上溢
以A=4,B=5为例:
如果存在上溢,则代表非符号位的最高位一定是“1+1”型,即会有最高数值位的进位,将符号位的0给覆盖,所以最高数值位的进位
。
但由于符号位都为0,所以不可能产生符号位的进位,所以符号位的进位
。
(2)下溢
以A=-4,B=-5为例:
如果存在下溢,则代表符号位一定是“1+1”型(无论是否存在下溢都是这样的,因为负+负即符号位1+1,是一定会有一个符号位的进位),且非符号位的最高位不存在进位(这是关键),因为如果非符号位的最高位有进位,则会将符号位又变为1,所以最高数值位的进位
,符号位的进位
。
三、采用双符号位
1.结论
双符号位是将原先的一个符号位复制一遍变成两个符号位,即正数符号位变为00,负数符号位变为11,结果的两个符号位分别记为
和
。
溢出判断:
。
另外,实际内存中只存储一个符号位,多出的符号位是运行时复制的,所以这种方法并不会多占用一位内存。
举个栗子:
两个四位(含一位符号位)的二进制数,A和B,A=4,B=5,[A+B]补 = 00,100+00,101 = 01,001。,
,
和
相异或为1,所以溢出。
2.解释
其实这个方法和方法二是等价的,我们直接将方法二的图改巴改巴。
(1)上溢
以A=4,B=5为例:
正数相加符号位都为0,简化思考可以直接当做没有。
如果存在上溢,则代表非符号位的最高位一定是“1+1”型,即会有最高数值位的进位,将符号位的0给覆盖,所以
。
但由于第二位符号位都为0,所以不可能产生符号位的进位,也就不存在更改第一位符号位的可能,所以
。
。
(2)下溢
以A=-4,B=-5为例:
虽说多出来一位符号位但结果其实是一样的,因为对于
,由于1+1=10向高位进一位,1超出存储范围不予保留,所有在不考虑后面进位的情况下其结果还是0。
看结果,跟方法二是一样的,由于非符号位的最高位不存在进位,所以
,由于第二位符号位产生进位,所以
。
。
总结
经过上面对三个方法的讲解,大家应该已经发现了:所谓溢出,其实就是俩负相加为正或俩正相加为负,也就是符号位与本应得的符号位不符。这三个方法看似不同,其实都是抓住了一个相同的点:如何看出结果符号位与本应得的符号位不同?
对于方法一,我们用结果符号位和两个加数的符号位比较的方法,正正得负或是负负得正那肯定溢出。
对于方法二和方法三,看似不同,实则都是采用向高位进位的思想,对于正正相加(即符号位0和0相加),肯定不存在符号位更高位(也就是我们常说的“进位位”)进位,所以和
肯定都为0,但由于符号位要由0变1,即加得为负,所以
和
都为0。对于负负相加(即符号位1和1相加),首先一定会有一个符号位向进位位的进位,所以
和
肯定都为1,但由于符号位要由1变0,即加得为正,所以
和
都为1。
若有错误,欢迎大家批评斧正!