Binary 什么是“;2';s补码”;?

Binary 什么是“;2';s补码”;?,binary,bit-manipulation,computer-science,twos-complement,data-representation,Binary,Bit Manipulation,Computer Science,Twos Complement,Data Representation,我学的是计算机系统课程,在某种程度上,我一直在努力学习。我想理解它,但我读过的每一篇文章都没有让我明白。我已经读过这本书和其他各种文章,包括 因此,我想开始这篇社区wiki文章,来定义什么是二的补码,如何使用它,以及它在诸如强制转换(从有符号到无符号,反之亦然)、逐位操作和位移位操作等操作中如何影响数字 我希望的是一个清晰简洁的定义,程序员很容易理解。是一种存储整数的聪明方法,因此常见的数学问题很容易实现 要想理解,你必须想到这些数字 它基本上说, 对于零,使用所有0 对于正整数,开始计数,最

我学的是计算机系统课程,在某种程度上,我一直在努力学习。我想理解它,但我读过的每一篇文章都没有让我明白。我已经读过这本书和其他各种文章,包括

因此,我想开始这篇社区wiki文章,来定义什么是二的补码,如何使用它,以及它在诸如强制转换(从有符号到无符号,反之亦然)、逐位操作和位移位操作等操作中如何影响数字

我希望的是一个清晰简洁的定义,程序员很容易理解。

是一种存储整数的聪明方法,因此常见的数学问题很容易实现

要想理解,你必须想到这些数字

它基本上说,

  • 对于零,使用所有0
  • 对于正整数,开始计数,最大值为2(位数-1)-1
  • 对于负整数,执行完全相同的操作,但是切换0和1的角色(因此,不要从0000开始,而是从1111开始-这是“补码”部分)
让我们尝试使用一个4位的小字节(我们称之为-1/2字节)

  • 0000
    -零
  • 0001
    -一个
  • 0010
    -两个
  • 0011
    -三个
  • 0100
    0111
    -四到七
这是我们能做的积极的事情。23-1=7

对于负片:

  • 1111
    -负数
  • 1110
    -负二
  • 1101
    -负三
  • 1100
    1000
    -负四至负八
请注意,对于负数(
1000
=-8),您会得到一个额外的值,而对于正数,您不会得到这个值。这是因为
0000
用于零。这可以被看作是计算机的一个例子

区分正数和负数

这样做,第一位获得“符号”位的角色,因为它可以用来区分非负和负十进制值。如果最高有效位是
1
,则二进制可以说是负数,其中最高有效位(最左边)是
0
,可以说十进制值是非负数

负数只是将正数对应的符号位翻转,但这种方法必须将
1000
(一个
1
,后跟所有
0
s)解释为“负零”,这很容易混淆

负数只是正数对应项的位补码,这也会导致将“负零”与
1111
(所有数字)混淆

除非您在非常接近硬件的地方工作,否则您可能不必处理一的补码或符号大小整数表示。

是一种存储整数的聪明方法,因此常见的数学问题很容易实现

要想理解,你必须想到这些数字

它基本上说,

  • 对于零,使用所有0
  • 对于正整数,开始计数,最大值为2(位数-1)-1
  • 对于负整数,执行完全相同的操作,但是切换0和1的角色(因此,不要从0000开始,而是从1111开始-这是“补码”部分)
让我们尝试使用一个4位的小字节(我们称之为-1/2字节)

  • 0000
    -零
  • 0001
    -一个
  • 0010
    -两个
  • 0011
    -三个
  • 0100
    0111
    -四到七
这是我们能做的积极的事情。23-1=7

对于负片:

  • 1111
    -负数
  • 1110
    -负二
  • 1101
    -负三
  • 1100
    1000
    -负四至负八
请注意,对于负数(
1000
=-8),您会得到一个额外的值,而对于正数,您不会得到这个值。这是因为
0000
用于零。这可以被看作是计算机的一个例子

区分正数和负数

这样做,第一位获得“符号”位的角色,因为它可以用来区分非负和负十进制值。如果最高有效位是
1
,则二进制可以说是负数,其中最高有效位(最左边)是
0
,可以说十进制值是非负数

负数只是将正数对应的符号位翻转,但这种方法必须将
1000
(一个
1
,后跟所有
0
s)解释为“负零”,这很容易混淆

负数只是正数对应项的位补码,这也会导致将“负零”与
1111
(所有数字)混淆


除非您的工作离硬件非常近,否则您可能不必处理一的补码或符号大小整数表示。

我想知道这是否比维基百科的文章解释得更好

用二的补码表示法试图解决的基本问题是存储负整数的问题

首先,考虑一个以4位存储的无符号整数。你可以有以下几点

0000 = 0
0001 = 1
0010 = 2
...
1111 = 15
这些是无符号的,因为没有迹象表明它们是负数还是正数

符号大小和多余符号 要存储负数,可以尝试多种方法。首先,可以使用符号幅度表示法,将第一位指定为符号位以表示+/-,其余位表示幅度。再次使用4位,假设1表示-,0表示+那么你就有了

0000 = +0
0001 = +1
0010 = +2
...
1000 = -0
1001 = -1
1111 = -7

0010 1001 + ----

 2  =  0010
 -3 =  1101 +
 -------------
 -1 =  1111
00
01
02
..
98
99
00
00001010
11110100
-----------------
11111110  
  // 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;
                  35=035=000000035.
       [0101]=[00101]=[00000000000101]=5 (base 10)
       [1011]=[11011]=[11111111111011]=-5(base 10)
        if a >= 0 then |a| = a
        if a < 0 then |a| = -a = 2scomplement of a
        1'scomp(0101) = 1010.
        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  Carry                      00000   Carry
     0110          is the same as     00110
    -0111                            +11001
  ----------                        ----------
sum  0101                       sum   11111
 1 1 1
 ----------
   1 0 1
 1 0 1 1 ---> additive inverse
  ---------
   0 0 0
x = 5;
x = -5;