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

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


当前回答

补一词来源于完备性。在十进制世界中,数字0到9提供了一个数字或数字符号的补集(完整集)来表示所有的十进制数。在二进制世界中,数字0和1提供了一个数字的补数来表示所有二进制数。事实上,符号0和1必须用来表示所有东西(文本、图像等)以及正(0)和负(1)。 在我们的世界里,数字左边的空白被认为是零:

                  35=035=000000035.

In a computer storage location there is no blank space. All bits (binary digits) must be either 0 or 1. To efficiently use memory numbers may be stored as 8 bit, 16 bit, 32 bit, 64 bit, 128 bit representations. When a number that is stored as an 8 bit number is transferred to a 16 bit location the sign and magnitude (absolute value) must remain the same. Both 1's complement and 2's complement representations facilitate this. As a noun: Both 1's complement and 2's complement are binary representations of signed quantities where the most significant bit (the one on the left) is the sign bit. 0 is for positive and 1 is for negative. 2s complement does not mean negative. It means a signed quantity. As in decimal the magnitude is represented as the positive quantity. The structure uses sign extension to preserve the quantity when promoting to a register [] with more bits:

       [0101]=[00101]=[00000000000101]=5 (base 10)
       [1011]=[11011]=[11111111111011]=-5(base 10)

用作动词: 2的补语表示否定。这并不意味着消极。意思是如果负数变成正数;如果是正的就是负的。大小是绝对值:

        if a >= 0 then |a| = a
        if a < 0 then |a| = -a = 2scomplement of a

此功能允许使用先求负后加的有效二进制减法。 A -b = A + (-b)

1的补数的官方方法是每一位数用1减去它的值。

        1'scomp(0101) = 1010.

这与逐个翻转或反转每一位是一样的。结果是- 0,这是不受欢迎的,所以给te 1的补码加上1就解决了这个问题。 要求2s的补,先求1s的补,然后加1。

        Example 1                             Example 2
         0101  --original number              1101
         1's comp  1010                       0010
         add 1     0001                       0001
         2's comp  1011  --negated number     0011

在这些例子中,否定也适用于符号扩展数。

添加: 1110进位111110进位 0110与000110相同 1111年 111111年 Sum 0101 Sum 000101

减法:

    1110  Carry                      00000   Carry
     0110          is the same as     00110
    -0111                            +11001
  ----------                        ----------
sum  0101                       sum   11111

请注意,当使用2的补码时,数字左侧的空白区域对于正数用0填充,而对于负数用1填充。进位总是被加上,必须是1或0。

干杯

其他回答

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

你试图用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。

哒哒!

想象一下,你有有限数量的比特/比特/数字等等。将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/

就像我看到的大多数解释一样,上面的解释清楚地说明了如何使用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会这样做似乎很自然,但这是出乎意料的,完全不是我们习惯的行为,因为除了计算机,我们通常认为数字是无限供应的,而不是这种固定长度的算术。

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