我在上一门计算机系统课程,在某种程度上,我一直在为“二的补充”而挣扎。我想了解它,但我所读到的一切并没有让我明白它的含义。我读过维基百科的文章和其他各种文章,包括我的课本。
什么是2的补数,我们如何使用它,它如何在强制转换(从有符号到无符号,反之亦然)、逐位操作和位移位操作等操作中影响数字?
我在上一门计算机系统课程,在某种程度上,我一直在为“二的补充”而挣扎。我想了解它,但我所读到的一切并没有让我明白它的含义。我读过维基百科的文章和其他各种文章,包括我的课本。
什么是2的补数,我们如何使用它,它如何在强制转换(从有符号到无符号,反之亦然)、逐位操作和位移位操作等操作中影响数字?
当前回答
最简单的答案:
1111 + 1 =(1)0000。所以1111一定是-1。那么-1 + 1 = 0。
理解这些对我来说是完美的。
其他回答
想象一下,你有有限数量的比特/比特/数字等等。将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的补语:当我们用一个数字的1的补语加一个额外的1时,我们将得到2的补语。例如:100101,它的1的补足是011010和2的补足是011010+1 = 011011(通过与1的补足相加) 本文以图解的方式对此进行了解释。
最简单的答案:
1111 + 1 =(1)0000。所以1111一定是-1。那么-1 + 1 = 0。
理解这些对我来说是完美的。
就像我看到的大多数解释一样,上面的解释清楚地说明了如何使用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's complement is essentially a way of coming up with the additive inverse of a binary number. Ask yourself this: Given a number in binary form (present at a fixed length memory location), what bit pattern, when added to the original number (at the fixed length memory location), would make the result all zeros ? (at the same fixed length memory location). If we could come up with this bit pattern then that bit pattern would be the -ve representation (additive inverse) of the original number; as by definition adding a number to its additive inverse always results in zero. Example: take 5 which is 101 present inside a single 8 bit byte. Now the task is to come up with a bit pattern which when added to the given bit pattern (00000101) would result in all zeros at the memory location which is used to hold this 5 i.e. all 8 bits of the byte should be zero. To do that, start from the right most bit of 101 and for each individual bit, again ask the same question: What bit should I add to the current bit to make the result zero ? continue doing that taking in account the usual carry over. After we are done with the 3 right most places (the digits that define the original number without regard to the leading zeros) the last carry goes in the bit pattern of the additive inverse. Furthermore, since we are holding in the original number in a single 8 bit byte, all other leading bits in the additive inverse should also be 1's so that (and this is important) when the computer adds "the number" (represented using the 8 bit pattern) and its additive inverse using "that" storage type (a byte) the result in that byte would be all zeros.
1 1 1
----------
1 0 1
1 0 1 1 ---> additive inverse
---------
0 0 0