假设我要减去:0000 0000 - (-1)
即:(二补)
0000 0000
- 1111 1111
---------
= ???? ????
会发生什么,我的大脑现在真的和我在一起,之前一切都很好,我认为它的溢出把我搞砸了,有人可以澄清一下吗:)?
假设我要减去:0000 0000 - (-1)
即:(二补)
0000 0000
- 1111 1111
---------
= ???? ????
会发生什么,我的大脑现在真的和我在一起,之前一切都很好,我认为它的溢出把我搞砸了,有人可以澄清一下吗:)?
取减数的二进制补码并将其添加到被减数。
0000 0000
- 1111 1111
...
0000 0000
+ 0000 0001
-----------
0000 0001
您可以通过添加其二进制补码 1(二进制 0000 0001)来减去 -1(二进制 1111 1111)。因此,在十进制中,0-(-1)=0+1=1 :-)
它将是(-11..11)。就像在小数中一样,符号仍然是符号,并且 (0-x) 仍然是 (-x),除非您使用按位运算而不是简单的减法。
我的直觉告诉我0 - (-1)
应该等于0+1
,或者干脆1
。
如果你想知道为什么,试着一点一点地执行减法:
0 - 1 = 10 - 1 = 1, setting borrow to 1.
0 - 1 - borrow = 10 - 1 - 1 = 0, borrow = 1
etc..
最好避免手动进行二进制减法。2s 补码的想法是通过添加倒数来提供一种执行减法的简单方法。
硬件的方式是将第二个操作数取反,并在最低有效位通道上执行加法,进位为 1。因此,加法是进位为零的加法,而 sub 是与操作数 notted 和进位设置。
你可以用铅笔和纸的方式,从旁边的数字中借用,但与十进制数字相比,感觉有点傻。用十进制数说 1000 减 1 右边的 0 变成 10,因为这是以 10 为底,然后它旁边的 0 也必须借用使其成为 10,然后向右边借出 1 使其成为 9,这继续直到你的第一行是 9 9 10 并且你减去 0 0 1 并得到 999。用底数 2 0b1000(这是十进制的八位)减去 0b0001,同样的事情发生在右边的零从左边借来变成 2 或 0b10,因为这是底数 2,它旁边的零必须借用成为 0b10,然后将一个借到右边使其成为 1,依此类推,所以你的顶行是 1 1 0b10,底行是 0 0 1 减去列,你得到 0b111 或 7 十进制。
所以全零减去全一,在第一次借位后,第一行是 1 1 1 1 1 1 1 0b10,最后一行保持为 0 0 0 0 0 0 0 0,减去列,你得到 0 0 0 0 0 0 0 1。