我只是好奇是否有理由为什么为了用二进制表示-1而使用二进制补码:翻转位并加1?
-1 由 11111111 (二进制补码)而不是(对我来说更直观) 10000001 表示,它是二进制 1,第一位作为负标志。
免责声明:我的工作不依赖二进制算术!
这样做是为了让加法不需要任何特殊的逻辑来处理负数。查看维基百科上的文章。
假设你有两个数字,2 和 -1。在您表示数字的“直观”方式中,它们分别是0010和1001(我坚持使用 4 位的大小)。在两者的补码方式中,它们是0010和1111。现在,假设我想添加它们。
0010
1001
1111
二进制补码加法非常简单。您通常添加数字,最后的任何进位位都会被丢弃。所以他们添加如下:
0010 + 1111 =10001 = 0001 (discard the carry)
0001为 1,即“2+(-1)”的预期结果。
0001
但是在您的“直观”方法中,添加更加复杂:
0010 + 1001 = 1011
哪个是-3,对吗?在这种情况下,简单的添加不起作用。您需要注意其中一个数字是负数,如果是这种情况,请使用不同的算法。
对于这种“直观”的存储方法,减法是与加法不同的操作,需要对数字进行额外检查,然后才能相加。由于您希望最基本的运算(加法、减法等)尽可能快,因此您需要以一种可以让您使用最简单算法的方式存储数字。
此外,在“直观”的存储方法中,有两个零:
0000 "zero" 1000 "negative zero"
它们直观上是相同的数字,但在存储时有两个不同的值。每个应用程序都需要采取额外的步骤来确保非零值也不是负零。
以这种方式存储整数还有另一个好处,那就是当您需要扩展存储值的寄存器的宽度时。使用二进制补码,将 4 位数字存储在 8 位寄存器中是重复它的问题最重要的位:
0001 (one, in four bits) 00000001 (one, in eight bits) 1110 (negative two, in four bits) 11111110 (negative two, in eight bits)
这只是查看较小单词的符号位并重复它直到它填充较大单词的宽度的问题。
使用您的方法,您需要清除现有位,这是除了填充之外的额外操作:
0001 (one, in four bits) 00000001 (one, in eight bits) 1010 (negative two, in four bits) 10000010 (negative two, in eight bits)
在这两种情况下,您仍然需要设置额外的 4 位,但在“直观”的情况下,您还需要清除第 5 位。这是每个应用程序中存在的最基本和最常见的操作之一中的一个微小的额外步骤。