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

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


当前回答

通过对给定数的第1个补数加1,可以求出两个补数。 假设我们要求出10101的两个补,然后求出它的一个补,也就是,在这个结果上加1,也就是,01010+1=01011,这就是最终答案。

其他回答

就像我看到的大多数解释一样,上面的解释清楚地说明了如何使用2的补码,但并没有真正解释它们在数学上是什么。我会试着这么做,至少对整数来说是这样的,我会先介绍一些你们可能熟悉的背景知识。

回想一下它是如何用于十进制的:2345是2 × 103 + 3 × 102 + 4 × 101 + 5 × 100的一种写法。

同样地,二进制是一种只使用0和1来写数字的方法,遵循相同的思路,但把上面的10换成了2。然后在二进制中,1111是1 × 23 + 1 × 22 + 1 × 21 + 1 × 20的一种写法,如果你算出来,结果等于15(以10为底)。因为8+4+2+1 = 15。

这对于正数来说很好。它甚至适用于负数,如果你愿意在负数前面加一个负号,就像人类对待小数一样。在某种程度上,这甚至可以在计算机上完成,但我从20世纪70年代初就没见过这样的计算机了。我将把原因留到另一个讨论。

对于计算机来说,负数使用补表示法效率更高。这里有一些经常被忽视的东西。补表示法涉及到数字数字的某种反转,甚至是在正常正数之前隐含的零。这很尴尬,因为问题来了:所有这些?这可能是一个无限的数字要考虑。

幸运的是,计算机并不代表无穷。数字被限制在特定的长度(或者宽度,如果你喜欢)。所以让我们回到正二进制数,但有一个特定的大小。在这些例子中,我将使用8个数字(“位”)。所以我们的二进制数应该是00001111或者0 × 27 + 0 × 26 + 0 × 25 + 0 × 24 + 1 × 23 + 1 × 22 + 1 × 21 + 1 × 20

为了形成2的补负,我们首先将所有的(二进制)数字补成11110000,然后加上1,形成11110001,但我们如何理解这意味着-15?

The answer is that we change the meaning of the high-order bit (the leftmost one). This bit will be a 1 for all negative numbers. The change will be to change the sign of its contribution to the value of the number it appears in. So now our 11110001 is understood to represent  -1 × 27 + 1 × 26 + 1 × 25 + 1 × 24 + 0 × 23 + 0 × 22 + 0 × 21 + 1 × 20Notice that "-" in front of that expression? It means that the sign bit carries the weight -27, that is -128 (base 10). All the other positions retain the same weight they had in unsigned binary numbers.

算出-15,就是-128 + 64 + 32 + 16 + 1用计算器试试。它是-15。

Of the three main ways that I've seen negative numbers represented in computers, 2's complement wins hands down for convenience in general use. It has an oddity, though. Since it's binary, there have to be an even number of possible bit combinations. Each positive number can be paired with its negative, but there's only one zero. Negating a zero gets you zero. So there's one more combination, the number with 1 in the sign bit and 0 everywhere else. The corresponding positive number would not fit in the number of bits being used.

关于这个数字更奇怪的是,如果你试图通过互补和加1来形成正数,你会得到相同的负数。0会这样做似乎很自然,但这是出乎意料的,完全不是我们习惯的行为,因为除了计算机,我们通常认为数字是无限供应的,而不是这种固定长度的算术。

这只是怪胎的冰山一角。表面之下还有更多的东西在等待着,但这就足够我们讨论了。如果你研究定点算术中的“溢出”,你可能会发现更多。如果你真的想深入了解它,你可能还会研究“模算术”。

按位补一个数就是将其中的所有位翻转。对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制作了一个关于这个主题的视频。

想象一下,你有有限数量的比特/比特/数字等等。将0定义为所有数字都为0,并自然向上计数:

00
01
02
..

最终你会溢出。

98
99
00

我们有两位数字,可以表示从0到100的所有数字。所有这些数字都是正数!假设我们也想表示负数?

我们真正拥有的是一个循环。2之前的数字是1。1之前的数字是0。0之前的数字是…99.

为了简单起见,我们设任何大于50的数都是负数。0 ~ 49代表0 ~ 49。“99”是-1,“98”是-2,…“50”是-50。

这个表示是十的补数。计算机通常使用2的补码,除了使用位而不是数字之外,它是一样的。

10的补数的好处在于加法运算可以正常进行。你不需要做任何特殊的加法和负数!

简单来说,2的补码是一种在计算机内存中存储负数的方法。而正数则存储为普通二进制数。

让我们考虑这个例子,

计算机使用二进制数字系统来表示任何数字。

x = 5;

这表示为0101。

x = -5;

当计算机遇到-号时,它会计算出它的2的补数并存储它。

也就是说,5 = 0101,它的2的补是1011。

计算机处理数字的重要规则是,

如果第一位是1,那么它一定是负数。 如果除第1位之外的所有位都是0,那么它就是一个正数,因为在数字系统中没有-0(1000不是-0,而是正8)。 如果所有的位都是0,那么它就是0。 否则就是正数。

你也可以使用在线计算器来计算一个十进制数的补二表示:http://www.convertforfree.com/twos-complement-calculator/