【问题标题】:Good explanation on why x-1 "looks" the way it does in binary很好地解释了为什么 x-1 “看起来” 像它在二进制中的方式
【发布时间】:2021-01-18 15:24:34
【问题描述】:

让我们取二进制数28

0b11100     # 28

如果我们从数字中减去1,它看起来像这样:

0b11011     # 27

我如何解释它的“外观”是,当从一个数字中减去1 时,最右边的 1 位设置为零,之后的所有零都设置为 1。例如:

  0b10101 - 1
= 0b10100

  0b01000 - 1
= 0b00111

  0b10000000 - 1
= 0b01111111

对于为什么会发生这种情况,最好的解释是什么?我确信这是二进制补码的一个属性,但我正在尝试找出向自己解释这一点的最佳方法,以便我能够更深入地理解它。

【问题讨论】:

  • 既然您已经看到了这种情况,还有什么要了解的?当它达到 1(然后被重置)时,借款停止,就是这样
  • @harold 是的...也许只是对为什么会发生这种情况的清晰解释,即如果左边的数字是 0,为什么 1 在借位时会向上波动,或者不是。我想我明白了,只是不太清楚为什么它会在我的脑海中发生。

标签: binary bit-manipulation twos-complement


【解决方案1】:

二进制数具有N = dn x b^n + dn-1 x b^n-1… d1 x b^1 + d0 x b^0 的一般形式,其中 b 是基数 (2),d 是数字

我们写下没有 b 的二进制数(因为我们知道它总是 2),也没有它的 n 指数,它从 0 隐含地表示最低有效位(最右边),1 到最右边,等等。

例如你的数字 28 是 1x 2^4 + 1x 2^3 + 1x 2^2 + 0x 2^1 + 0x 2^0 = 1x 16 + 1x 8 + 1x 4 + 0x 2 + 0x 1。

二进制:

  • 1 - 1 = 0
  • 0 - 1 = 1,然后将 - 1 进位到左边的下一个位置(与十进制的 10 - 1 相同,0 - 1 是 9,进位 - 1 到十分之一)

当减去 1 时,您从最右边的位置开始,如果有 0,则将其变为 1 并将减法带到下一个(左侧)位置(并且一直向左链接,直到找到可以减去而不影响更高位置的位置位置)

0b01000 - 1 可以写成 0x 2^4 + 1x 2^3 + 0x 2^2 + 0x 2^1 + 0x 2^0 - 1 x 2^0。用简单的十进制表示,即 8 - 1 = 7,二进制表示 7 是 0x 2^4 + 0x 2^3 + 1x 2^2 + 1x 2^1 + 1x 2^0 (4 + 2 + 1)

【讨论】:

    【解决方案2】:

    无论你在什么基础上,数学都不会改变:

      1000 
    - 0001
    ========
    

    这是以 10 为底的,更容易看到:

      1  0  0  0 
    - 0  0  0  1
    =============
    

    我们从个数列开始(以 0 为底),顶部的数字小于底部的数字,所以我们必须借用,但我们发现下一列没有任何内容,以此类推,所以我们必须继续工作,直到我们可以借一些东西,该值的基数大于它所在的列,所以如果你从数百列借入 10 列的 10 列,那么:

    所以先借:

      0 10  0  0 
    - 0  0  0  1
    =============
    

    第二次借用:

      0  9 10  0 
    - 0  0  0  1
    =============
    

    第三次借用:

      0  9  9 10 
    - 0  0  0  1
    =============
    

    现在我们可以将基础工作到一列的幂:

      0  9  9 10 
    - 0  0  0  1
    =============
               9
    

    在这种情况下可以轻松完成:

      0  9  9 10 
    - 0  0  0  1
    =============
      0  9  9  9
    

    所以基数为 5:

        1  0  0  0
     -  0  0  0  1
    ===================
    
        0  5  0  0
     -  0  0  0  1
    ===================
    
        0  4  5  0
     -  0  0  0  1
    ===================
    
        0  4  4  5
     -  0  0  0  1
    ===================
    
    
        0  4  4  5
     -  0  0  0  1
    ===================
        0  4  4  4
    

    基数为 2:

       1  0  0  0
    -  0  0  0  0 
    ==============
    
       0 10  0  0
    -  0  0  0  0 
    ==============
    
       0  1 10  0
    -  0  0  0  0 
    ==============
    
       0  1  1 10
    -  0  0  0  0 
    ==============
    
       0  1  1 10
    -  0  0  0  0 
    ==============
       0  1  1  1
    

    当您在逻辑中实际实现这一点时,二进制补码就会发挥作用,我们从初级编程课程中知道,当我们谈论“二进制补码”时,我们会学习“反转和加一”来否定一个数字。我们从小学数学中知道 x - y = x + (-y) 所以:

         0
      1000
    - 0001
    =======
    

    这与:

         1 <--- add one
      1000
    + 1110 <--- invert
    =======
    

    完成:

     10001
      1000
    + 1110
    =======
      0111
    

    因此,对于减法,您反转/一个补充第二个操作数和进位并将它们提供给加法器。一些架构反转进位并将其称为借用,有些则保持不变。正如我们在上面看到的那样这样做时,如果没有借位,则执行是 1。如果有借位,则为零。

    我相信这只是因为只有 0 或 1,所以这是一个 base 2 的事情。你如何反转一个基数为 10 的数字? 1000 - 1 = 1000 + 9998 + 1,嗯,确实可行。

    所以底数 10 100 - 1 = 99,底数 9 100 - 1 = 88,底数 8(八进制)100 - 1 = 77,底数 7 100 - 1 = 66 等等。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-13
      • 2014-07-11
      • 2021-10-03
      • 1970-01-01
      • 2020-01-22
      相关资源
      最近更新 更多