二进制数系统中算术加法中的溢出

17 Mar 2025 | 6 分钟阅读

为了解释算术加法溢出,我们主要使用二进制补码系统,这是一种在计算机体系结构中广泛使用的数制。

  • 如果二进制补码系统有N位,它可以表示从 -2n-1 到 2n-1-1 的数字。
  • 如果二进制补码系统有4位,它将表示从 (-8 到 7) 的数字。
  • 如果二进制补码系统有5位,它将表示从 (-16 到 15) 的数字。

当我们尝试添加两个N位二进制补码数,并且生成的输出太大以至于无法放入该N位组时,在这种情况下,就会发生加法溢出。系统或计算机中通常有N位固定寄存器。当我们添加两个N位数字时,它将生成最大N+1位数字的输出。在进位标志的帮助下,这个额外的位被存储。问题是进位并不总是用于表示溢出。

例如:在此示例中,我们将借助二进制补码来添加7和1。

解决方案:二进制数7(0001)和7(0111)的加法描述如下

正如我们所看到的,用4位表示7 + 1等于8。但是我们不能用4位二进制补码数表示8,因为数字8超出范围。当我们添加两个正数时,我们却得到一个负数(-8)。在此示例中,0也是进位。通常,与溢出相关的问题留给程序员处理。

溢出检测

在显示算术运算结果时,如果位数不足以表示二进制数,就会发生溢出。计算机算术在除法、减法、乘法和减法方面是封闭的;因此会发生溢出。如果操作数的符号不同(或相同),在这种情况下,溢出将不会发生。

溢出发生有两种情况,描述如下:

  1. 当我们尝试添加两个负数,而结果是一个正数时。
  2. 当我们尝试添加两个正数,而结果是一个负数时。

例如

输入输出
A符号位B符号位进位(CARRY IN)出位(CARRY OUT)符号位溢出(OVERFLOW)
000000
001011
010010
011100
100010
101100
110101
111110

当两个正数相加,结果是正数;当两个负数相加,结果是负数时,不会发生溢出,描述如下:

输入输出
A符号位B符号位进位(CARRY IN)出位(CARRY OUT)符号位溢出(OVERFLOW)
000000
00101?
010010
011100
100010
101100
11010?
111110

如果我们有 N 位数字表示,那么我们需要 N + 1 位来检测和补偿溢出。例如:假设我们有 32 位算术,我们可以借助 33 位来检测和补偿溢出。我们可以利用符号位中产生的进位(借位)来实现加法中的这一点。为了更深入地解释,我们将借助数字 7 和 6 的四位二进制表示来提供四种不同的符号组合。

Overflow in Arithmetic Addition in Binary number System

我们可以使用2位比较器而不是3位比较器来检测溢出。我们还可以通过检查两个数字的MSB及其结果来检测溢出。为此,我们只需检查最高有效位的进位(C-in)和出位(C-out)。假设我们将执行N位二进制补码数的加法,描述如下:

Overflow in Arithmetic Addition in Binary number System

当C-in和C-out彼此相等时,将发生溢出。借助以下分析,我们可以解释上述溢出表达式。

Overflow in Arithmetic Addition in Binary number System

在第一张图片中,0表示两个数字的最高有效位,表示它们是正数。如果我们得到1作为进位,最高有效位的结果也将是1,这意味着结果是负数(溢出)。在这种情况下,出位也将是0。这证明进位和出位不相等,因此发生溢出。

在第二张图片中,1表示两个数字的最高有效位,表示它们是负数。如果我们得到0作为进位,最高有效位的结果也将是0,这意味着结果是正数(溢出)。在这种情况下,出位也将是1。这证明进位和出位不相等,因此发生溢出。

根据上述解释,我们可以说溢出可以通过MSB(最高有效位)的C-in和C-out来检测,描述如下:

Overflow in Arithmetic Addition in Binary number System

借助上述异或门,我们可以轻松检测溢出。

溢出条件

溢出有多种条件,描述如下:

  • 算术运算有可能发生溢出条件。
  • 溢出取决于容纳结果的数据类型的大小。
  • 如果结果的数据类型过小或过大,无法放入原始数据类型中,则会发生溢出。
  • 当我们尝试添加两个有符号的2的补码数字时,如果两个数字都是正数且生成的结果为负数,或者两个数字都是负数且生成的结果为正数,则会发生溢出。
  • 当我们尝试添加两个无符号数时,如果最左边的位包含进位输出,则会发生溢出。

无符号数相加的例子

在这个例子中,我们使用一位量来检测一位量是否包含溢出。

在这个例子中,我们可以看到最后一行包含一个进位输出。这意味着我们无法用一位量来容纳(1 + 1)。如果我们要成功完成{1 + 1},我们需要更大的数据类型。当我们尝试添加多位无符号数时,当且仅当最左边的有效位包含进位输出时才会发生溢出。

有符号数相加的例子

在此示例中,我们使用一位有符号量,并检测该一位量是否包含溢出。

解决方案:这里,一位用于表示符号,另一位用于表示数据。因此,我们需要两位有符号数据类型,描述如下:

二元十进制
符号位数据位
000
011
11-1
10-2

假设我们有两个符号相反的数字。如果我们将这些数字相加,它们的和永远不会溢出,如下所示:

但是如果两个数字的符号相同,它们的和可能会溢出,如下所示:

因此,输出 {2, -4, -3} 无法适应两位有符号数据类型。