02 Addition and Subtraction
加法就和我们手算一样,从右往左一位一位相加,需要进位的话,左边一位多加一。减法就是加上被减数的相反数,如果用补码表示,直接相加即可。
现在 CPU 最差情况只需要 的复杂度就能完成加法的计算,其中 是比特数。
Binary Addition and Subtraction
下面是十进制 6 和 7 相加。
下面是直接做减法。 如果使用补码表示 -6,那么就是加法操作。什么时候发生溢出呢?如果加法的操作数的符号不一样,那么不会发生溢出,因为结果不会大于任意一个加数。
减法可以写成加上被减数的相反数,因此如果减法中的两个数符号一样,变成加法后两个操作数符号不一样,也就不会溢出。
如果两个操作数是 32 比特,而结果必须使用 33 比特来表示,此时就溢出了。当出现这种情况时,符号位是错误结果。当加两个整数时,结果是负数,那么就溢出了。反之亦然。
减法正好相反。一个正数减去一个负数,得到一个负数表示溢出了。反之,一个负数减去一个正数,得到一个正数表示溢出了。
下表整理了这几种情况。
操作 | 操作数 A | 操作数 B | 溢出结果 |
---|---|---|---|
A+B | |||
A+B | |||
A-B | |||
A-B |
如果操作数是无符号数呢?通常,无符号数表示地址,会忽略溢出。
计算机中,执行加减法的模块我们称为算术逻辑单元(Arithmetic Logic Unit
, ALU
)。这个模块还可以执行逻辑运算,比如与、或。
对于 C 和 Java 而言,不会检查是否溢出,不过像 Ada 和 Fortran,需要知道是否溢出,所以 CPU 的设计者需要确定如何处理溢出。