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

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


当前回答

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

我把所有位的倒数加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;

其他回答

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

我把所有位的倒数加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;

最简单的答案:

1111 + 1 =(1)0000。所以1111一定是-1。那么-1 + 1 = 0。

理解这些对我来说是完美的。

2的补码是表示负数的一种方式,大多数控制器和处理器都以2的补码形式存储负数。

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

到目前为止,许多答案都很好地解释了为什么2的补数被用来表示负数,但没有告诉我们2的补数是什么,尤其是没有告诉我们为什么加了一个“1”,而且实际上经常以错误的方式加。

这种混淆来自于对补数定义的不理解。补语是指使某物完整的缺失部分。

根据定义,n位数x以b为基数的基数补是b^n-x。

在二进制中,4由100表示,它有3位数字(n=3)和基数2 (b=2)。所以它的基数补是b^n-x = 2^3-4=8-4=4(或二进制的100)。

然而,在二进制中,求一个基数的补并不像求它的消简基数补那么容易,消简基数补定义为(b^n-1)-y,只比基数补小1。要得到一个减少的基数补,只需翻转所有的数字。

100 -> 011(减基数补位)

为了得到基数(2的)补,我们只需按定义加1。

011 +1 ->100(2的补码)。

现在,有了这个新的理解,让我们看看Vincent Ramdhanie给出的例子(见上面的第二个回答):

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

应理解为:

数字从1开始,所以是负的。所以我们知道它是x的一个2的补。为了找到由它的2的补表示的x,我们首先需要找到它的1的补。

x的2的补数是1111 x的补数:1111-1 ->1110; X = 0001,(翻转所有数字)

应用符号-,结果=-x =-1。