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
(所有数字)混淆


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

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

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

首先,考虑一个以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 +
----
?

另一个系统是。你可以存储负数,你可以摆脱两个零的问题,但加法和减法仍然很困难

于是,二的补码出现了。现在,您可以相对轻松地存储正整数和负整数并执行算术。有许多方法可以将一个数字转换为二的补码。这里有一个

将十进制转换为二的补码
  • 将数字转换为二进制(暂时忽略符号) e、 g.5为0101,-5为0101

  • 如果这个数字是正数,那么就完成了。 e、 g.5是二进制的0101,使用2的补码表示法

  • 如果数字是负数,那么

    3.1求补码(0和1的倒数) e、 g-5是0101,所以求补码是1010

    3.2在补码1010+1=1011中加1。 因此,二的补码中的-5是1011

  • 那么,如果你想在二进制中做2+(-3)呢?2+(-3)等于-1。 如果您使用符号大小来添加这些数字,您需要做什么?0010+1101=

    用两个补体考虑它有多容易。

     2  =  0010
     -3 =  1101 +
     -------------
     -1 =  1111
    
    将二的补码转换为十进制 将1111转换为十进制:

  • 这个数字以1开头,所以是负数,所以我们找到1111的补码,也就是0000

  • 将1加到0000,我们得到0001

  • 将0001转换为十进制,即1

  • 应用符号=-1


  • 塔达

    我喜欢拉维尼奥的答案,但移位会增加一些复杂性。通常,在考虑符号位或不考虑符号位时,可以选择移动位。这是将数字视为有符号数字(半字节为8到7,字节为128到127)或全范围无符号数字(半字节为0到15,字节为0到255)之间的选择。

    假设您有有限数量的位/trits/位/任何数字。您将0定义为所有数字均为0,并自然向上计数:

    00
    01
    02
    ..
    
    最终你会溢出

    98
    99
    00
    
    我们有两个数字,可以代表从0到100的所有数字。所有这些号码都是po
    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;