我只是好奇,为了在二进制中表示-1,是否有一个原因,使用了2的补码:翻转位并加1?
-1由11111111(2的补码)表示,而不是(对我来说更直观)10000001,10000001是二进制1,第一位为负标志。
免责声明:我的工作不依赖二进制算术!
我只是好奇,为了在二进制中表示-1,是否有一个原因,使用了2的补码:翻转位并加1?
-1由11111111(2的补码)表示,而不是(对我来说更直观)10000001,10000001是二进制1,第一位为负标志。
免责声明:我的工作不依赖二进制算术!
当前回答
你的目的并不是把二进制数的所有位都颠倒过来。实际上就是用1减去每一位。这只是一个幸运的巧合,1减1得0,1减0得1。所以翻转位有效地执行了这个减法。
但为什么每个数字的差值都是1呢?你不是。您的实际目的是计算给定的二进制数与另一个具有相同位数但只包含1的二进制数的差值。例如,如果您的数字是10110001,当您翻转所有这些位时,您实际上是在计算(11111111 - 10110001)。
这解释了计算二的补的第一步。现在让我们在图中加入第二步——添加1。
将上述二进制方程加1:
11111111-10110001 + 1
你得到了什么?这样的:
100000000-10110001
这是最终方程。通过执行这两个步骤,你试图找到这个,最终的区别:二进制数减去另一个二进制数,多出一位,并且除最高位外都包含零。
但我们为什么要追求这种差异呢?好吧,从现在开始,我想你最好去读维基百科的文章。
其他回答
2的补数允许以正常的方式进行加减法(就像对无符号数字进行绕线运算一样)。它还防止了-0(一种单独的表示0的方法,如果使用常规的逐位比较数字的方法,它将不等于0)。
这样加法就不需要任何特殊的逻辑来处理负数了。在维基百科上查看这篇文章。
假设有两个数,2和-1。在表示数字的“直观”方式中,它们将分别为0010和1001(我坚持使用4位的大小)。两者互为补足,分别是0010和1111。现在,假设我想把它们相加。
2的补语加法非常简单。你通常加数字,任何进位在最后被丢弃。所以它们相加如下:
0010
+ 1111
=10001
= 0001 (discard the carry)
0001是1,这是“2+(-1)”的预期结果。
但在你的“直观”方法中,添加更复杂:
0010
+ 1001
= 1011
等于-3,对吧?简单的加法在这种情况下行不通。你需要注意,其中一个数字是负的,如果是这种情况,就使用不同的算法。
对于这种“直观的”存储方法,减法是一种不同于加法的操作,在加法之前需要对数字进行额外的检查。由于您希望最基本的操作(加法、减法等)尽可能快,因此需要以允许您使用尽可能简单的算法的方式存储数字。
此外,在“直观”存储方法中,有两个0:
0000 "zero"
1000 "negative zero"
它们直观上是相同的数字,但存储时有两个不同的值。每个应用程序都需要采取额外的步骤来确保非零值也不是负零。
以这种方式存储int型还有另一个好处,那就是当你需要扩展存储值的寄存器的宽度时。对于2的补数,在8位寄存器中存储一个4位数就是重复它的最高位:
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位。这是每个应用程序中最基本和最常见操作之一中的一个小小的额外步骤。
为什么用Two2的补语系统来表示负数,而不是用One的补语系统,一个令人满意的答案是 二的补语系统解决了一的补语系统中存在的表示负数的0的多重表示和对进位的需要。
欲了解更多信息,请访问https://en.wikipedia.org/wiki/Signed_number_representations
用于末端绕行访问 https://en.wikipedia.org/wiki/End-around_carry
It's worthwhile to note that on some early adding machines, before the days of digital computers, subtraction would be performed by having the operator enter values using a different colored set of legends on each key (so each key would enter nine minus the number to be subtracted), and press a special button would would assume a carry into a calculation. Thus, on a six-digit machine, to subtract 1234 from a value, the operator would hit keys that would normally indicate "998,765" and hit a button to add that value plus one to the calculation in progress. Two's complement arithmetic is simply the binary equivalent of that earlier "ten's-complement" arithmetic.
我有一个在某些情况下很重要的小补充:在这些限制条件下,2的恭维是唯一可能的表示:
无符号数和二的补数是恒等交换环。它们之间有一个同态。 它们共享相同的表示,对负数有不同的分支切割,(因此,为什么它们之间的加法和乘法是相同的)。 高位决定符号。
要知道为什么,它有助于降低基数;例如Z_4。
星座、星等和一个人的赞美都不能形成一个具有相同数量元素的环;一个症状是双零。因此,很难在边缘上工作;为了在数学上保持一致,它们需要检查溢出或陷阱表示。