CPU如何区分溢出和自然进位?
之前学习补码的时候倒是学会了基本概念,但是最近又接触时发现还有不清楚的地方,所以又研究了下
今天的核心问题的“CPU是如何区分高位自然舍弃和溢出的?”
先给出结论:如果运算中,数值位最高位(也就是有符号数的正数第二位)和符号位(也就是正数第一位)同时进位,则是自然舍弃。两者间如果只有一个进位,则是溢出。
下面来讲解一下。运算的所有情况可以划分为四种:
- 符号位进位,数值最高位不进位
- 符号位不进位,数值最高位进位
- 符号位和数值最高位都进位
- 符号位和数值最高位都不进位
对于第四种情况,就没什么好说了,都不进位的话根本涉及不到区分的问题。
对于第一种和第二种情况都好理解:对于第一种情况,既然数值最高位没有进,那么符号位的进位就一定是完全由符号位导致的,也就是说符号位一定是两个1,那么这样进位的结果就是符号位为0——两个负数加法运算结果为正数,当然是溢出了。第二种也是同理,数值最高位进位了而符号位没有进,只能说明原来符号位是两个0,那么就是两个正数相加结果为负数,溢出无疑了。
比较复杂一点的是情况3,它又可以细分为:
- 两个数符号位都是1
- 一个数符号位为1,另一个是0
要讲清楚这里的内容,我们要了解一下究竟什么是溢出?我们以4位二进制数为例,它的表示范围是[-8,7]。注意,溢出是结果错误,但不是二进制加法本身有错误,我们所说的溢出,是指在对二进制加法的结果进行截取后,截取的结果和算术运算的结果不符,而造成溢出的原因就是计算的结果超出能表示的范围。而对于情况2,一个正确表示的正数和一个正确表示的负数相加,结果一定是不会超出表示范围的,这里的进位就只能是自然进位。对于1,两个负数相加什么情况下才会溢出呢?就是超出表示范围的情况,而对于负数,除了符号位之外,数值位0越多数就越小。在1的前提下,能找到的最小的负数就是1010和1110,其分别是-6和-2,加起来正好是-8不超范围。所以这种情况也被证明了不会溢出了。
综上,我们证明了只有在符号位和数值最高位两个里面只有一个进位的时候才是溢出,依次为据我们就可以设计CPU指令了。