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

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


当前回答

让我们用8位的二进制形式得到答案10 - 12: 我们要做的是10 + (-12)

我们需要用12的恭维部分减去10。 12的二进制值是00001100。 10的二进制值是00001010。

为了得到12的赞美部分,我们只需要把所有的位反转,然后加1。 12的二进制反转是11110011。这也是逆码(一个人的补码)。 现在我们需要加一个,现在是11110100。

所以11110100是12的赞美!这样想很简单。

现在你可以用二进制形式来解决上面的10 - 12问题了。

00001010
11110100
-----------------
11111110  

其他回答

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

按位补一个数就是将其中的所有位翻转。对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的补码是表示负数的一种方式,大多数控制器和处理器都以2的补码形式存储负数。

从数学的角度来看这两个补体系统是有道理的。在ten的补语中,这个想法本质上是“隔离”差异。

示例:63 - 24 = x

我们把24的补数相加,也就是(100 - 24)实际上,我们要做的就是在方程两边加100。

现在方程是:100 + 63 - 24 = x + 100,这就是为什么我们要去掉100(或10或1000或其他)。

由于必须从一长串零中减去一个数字的不方便情况,我们使用“减基数补”系统,在十进制系统中,9的补。

当我们看到一串大的9减去一个数时,我们只需要把数字倒过来。

例如:99999 - 03275 = 96724

这就是为什么在9的补数之后加1。你可能从儿时的数学中知道,9通过“偷走”1变成了10。所以基本上就是10的补位差减去1。

在二进制中,2的补数等于10的补数,而1的补数等于9的补数。主要的区别在于,我们不是试图用10的幂来分离差异(将10、100等添加到等式中),而是试图用2的幂来分离差异。

正是因为这个原因,我们把比特位颠倒。就像小数中的被减数是一串9一样,二进制中的被减数也是一串1。

例如:111111 - 101001 = 010110

因为1链比2的幂小1,它们从差值中“偷”了1,就像小数点中的9一样。

当我们使用负二进制数时,我们实际上是在说

0000 - 0101 = x

1111-0101 = 1010

1111 + 0000 - 0101 = x + 1111

为了“分离”x,我们需要加1,因为1111离10000只有1,我们去掉前导的1,因为我们只是把它加到原始的差值上。

1111 + 1 + 0000 - 0101 = x + 1111 + 1

10000 + 0000 - 0101 = x + 10000

只要两边都去掉10000就得到x,这是基本的代数。

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