我在上一门计算机系统课程,在某种程度上,我一直在为“二的补充”而挣扎。我想了解它,但我所读到的一切并没有让我明白它的含义。我读过维基百科的文章和其他各种文章,包括我的课本。

什么是2的补数,我们如何使用它,它如何在强制转换(从有符号到无符号,反之亦然)、逐位操作和位移位操作等操作中影响数字?


当前回答

按位补一个数就是将其中的所有位翻转。对2的补位,我们翻转所有的位,加1。

对有符号整数使用2的补码表示,我们应用2的补码操作将正数转换为负数,反之亦然。因此,以nibbles为例,0001(1)变成1111(-1),并再次应用该操作,返回0001。

零处操作的行为有利于给出零的单一表示,而无需特别处理正零和负零。0000与1111互补,当1111加1时。溢出到0000,得到一个0,而不是一个正1和一个负1。

这种表示的一个关键优点是,用于无符号整数的标准加法电路在应用于它们时产生正确的结果。例如,在nibbles中添加1和-1:0001 + 1111,比特溢出寄存器,留下0000。

作为一个温和的介绍,优秀的Computerphile制作了一个关于这个主题的视频。

其他回答

2的补语:当我们用一个数字的1的补语加一个额外的1时,我们将得到2的补语。例如:100101,它的1的补足是011010和2的补足是011010+1 = 011011(通过与1的补足相加) 本文以图解的方式对此进行了解释。

按位补一个数就是将其中的所有位翻转。对2的补位,我们翻转所有的位,加1。

对有符号整数使用2的补码表示,我们应用2的补码操作将正数转换为负数,反之亦然。因此,以nibbles为例,0001(1)变成1111(-1),并再次应用该操作,返回0001。

零处操作的行为有利于给出零的单一表示,而无需特别处理正零和负零。0000与1111互补,当1111加1时。溢出到0000,得到一个0,而不是一个正1和一个负1。

这种表示的一个关键优点是,用于无符号整数的标准加法电路在应用于它们时产生正确的结果。例如,在nibbles中添加1和-1:0001 + 1111,比特溢出寄存器,留下0000。

作为一个温和的介绍,优秀的Computerphile制作了一个关于这个主题的视频。

两人的补足(托马斯·芬利)

我把所有位的倒数加1。编程:

  // In C++11
  int _powers[] = {
      1,
      2,
      4,
      8,
      16,
      32,
      64,
      128
  };

  int value = 3;
  int n_bits = 4;
  int twos_complement = (value ^ ( _powers[n_bits]-1)) + 1;

我喜欢lavinio的回答,但变换部分增加了一些复杂性。通常情况下,可以选择在保留符号位的情况下移动位,或者不保留符号位。这是将数字处理为有符号数字(-8到7表示小块,-128到127表示字节)或全范围无符号数字(0到15表示小块,0到255表示字节)之间的选择。

我想知道是否有比维基百科上的文章更好的解释。

你试图用2的补表示法解决的基本问题是存储负整数的问题。

首先,考虑一个存储在4位的无符号整数。您可以拥有以下内容

0000 = 0
0001 = 1
0010 = 2
...
1111 = 15

这些是无符号的,因为没有指示它们是负的还是正的。

符号大小和多余符号

要存储负数,您可以尝试一些方法。首先,您可以使用符号幅度表示法,它将第一个位指定为符号位来表示+/-,其余位表示幅度。还是用4位假设1代表- 0代表+那么你就有

0000 = +0
0001 = +1
0010 = +2
...
1000 = -0
1001 = -1
1111 = -7

所以,你看到问题了吗?我们有正0和负0。更大的问题是二进制数的加减法。使用符号幅度进行加减法的电路将非常复杂。

是什么

0010
1001 +
----

?

另一个系统是过量符号。你可以存储负数,你可以摆脱两个0的问题但加减法仍然很困难。

于是就有了二的补。现在您可以存储正整数和负整数,并相对轻松地执行算术。有许多方法可以将一个数转换为二的补数。这是一个。

将十进制转换为二的补数

将数字转换为二进制(暂时忽略符号) 例如,5是0101,-5是0101 如果这个数字是正数,那么你就完成了。 例5是二进制的0101,使用二的补符号。 如果数字是负的,那么 3.1求补(0和1的倒数) 例如,-5是0101,所以找到补语是1010 3.2补数1010 + 1 = 1011加1 因此,2的补数-5等于1011。

那么,如果你想用二进制写2 +(-3)呢?2 +(-3) = -1。 如果你用符号的大小来加这些数,你需要做什么?0010 + 1101 = ?

使用2的补码,想想会有多简单。

 2  =  0010
 -3 =  1101 +
 -------------
 -1 =  1111

将2的补数转换为十进制

将1111转换为十进制:

这个数从1开始,所以它是负的,所以我们找到1111的补数,也就是0000。 0000加上1,得到0001。 将0001转换为十进制,即1。 应用符号= -1。

哒哒!