今天在课堂上,我的计算老师正在向我们解释(或试图解释)如何使用Two's Complement编写负二进制数。我的问题是:
最终用户如何确定11101100与236和-20之间的差异?我知道你总能查到最重要的一点,但这总是100%准确吗?是否使用负二进制数来使最高位指示符号?
旁注:
为什么我们可以学习二进制减法:
将二进制转换为denary - >减去否定 - >重新转换为二进制
答案 0 :(得分:21)
"负二进制数的约定是否使最高位指示符号?"
有多种方法可以用二进制表示负数。最常见的是您正在学习的两个补码表示。在该系统中,是的,最高位将指示数字的符号(如果0与正数分组)。
在标准无符号二进制数中,数字由位置符号的位序列表示(为简洁起见,我只使用三位):
b 2 b 1 b 0 = 2 2 b 2 + 2 1 b 1 + 2 0 b 0 = 4b 2 + 2b < sub> 1 + b 0
111 2 = 7 10
110 2 = 6 10
101 2 = 5 10
100 2 = 4 10
011 2 = 3 10
010 2 = 2 10
001 2 = 1 10
000 2 = 0 10
的两个&#39; S-补强>
有几种方法可以看待2s补码,我认为答案在所有这些方面都很明显。获得这个系统的一种方法是取无符号数的上半部分(都设置了高位)并将它们移到零以下:
011 2 = 3 10
010 2 = 2 10
001 2 = 1 10
000 2 = 0 10
111 2 = -1 10
110 2 = -2 10
101 2 = -3 10
100 2 = -4 10
您可以清楚地看到高位表示符号。同样,0取4个正表示中的一个,这导致范围不对称:[3,-4](尽管有时最负值被认为是特殊的,使可用范围对称)。同样,我们可以将最高位重新解释为负数:
b 2 b 1 b 0 = - (2 2 ) b 2 + 2 1 b 1 + 2 0 b 0 = -4 b 2 + 2b 1 + b 0
显然,由于高位具有比所有其他位组合更大的权重(在绝对值意义上),如果它被设置,则结果是负的。如果未设置,则所有剩余权重均为正数,因此结果也是如此。
根据这个定义,我们可以推导出第三种解释:-a = ~a + 1
(其中-
表示算术否定,~
表示按位互补,我们忽略溢出)的常见规则:
a + ~a = -4b 2 + 2b 1 + b 0 + -4(~b 2 )+ 2(~b 1 )+ ~b 0
a + ~a = -4(b 2 + ~b 2 )+ 2(b 1 + ~b 1 )+(b 0 + ~b 0 )
a + ~a = -4(1)+ 2(1)+(1)
a + ~a = -1
a = - (~a + 1)
-a = ~a + 1
在这里,我们看到否定翻转高位,因此它表示数字的符号。请注意,这不是严格 true,因为如果设置了所有其他位,则添加一个可以将高位翻转。但是,这只是0和最负数的情况(-4 10 ,或100 2 ,在这种情况下),当否定时两者都保持不变。
使用2s补码的好处是可以使用相同的硬件进行有符号和无符号加法。这个不错的属性不适用于过去使用的其他负二进制表示,其中一些我将简要介绍。由于这个事实,现代CPU几乎总是使用这种表示来进行整数运算(我不知道任何最近的商业反例,但它们可能在那里)。这就是为什么你要学习它(而不是Convert binary to denary -> subtract denary -> reconvert into binary
):了解操作如何在ALU的门级工作。
的一个&#39; S-补强>
1s-补体与2s-补体密切相关。通过仅反转位来执行否定(不添加1)。前导位仍然表示符号,但正负零有不同的表示。我从来没有亲自遇到过1s-complement的现实世界,但它具有历史意义。
b 2 b 1 b 0 = -3b 2 + 2b 1 + b 0
011 2 = 3 10
010 2 = 2 10
001 2 = 1 10
000 2 = 0 10
111 2 = -0 10
110 2 = -1 10
101 2 = -2 10
100 2 = -3 10
登录和幅度强>
符号和幅度最接近人类通常写负数的方式。低两位具有与上述系统相同的重量,高位没有(附加)重量。相反,仅会更改结果的符号。显然,这里的前导位表示符号。与1s补码一样,有两个0的表示。它现在仍然用于IEEE浮点数的尾数(尽管指数位于符号和幅度之间)。
b 2 b 1 b 0 = ( - 1) b 2 (2b 1 + b 0 )
0 11 2 = + 3 10
0 10 2 = + 2 10
0 01 2 = + 1 10
0 00 2 = + 0 10
1 00 2 = - 0 10
1 01 2 = - 1 10
1 10 2 = - 2 10
1 11 2 = - 3 10
的过量的正强>
Excess-n更像是一个系统系列。所有值都向上移动n(称为 bias ),然后表示为无符号情况。如果选择了正确的偏置,则前导位可以指示,但是具有与上述系统不同的极性(并且0可以与负数或正数组合)。这仍然用在IEEE浮点数的指数中。对于n = 3,高位确实表示符号,0表示负数:
b 2 b 1 b 0 = 4b 2 + 2b 1 + b 0 - n
111 2 = 4 10
110 2 = 3 10
101 2 = 2 10
100 2 = 1 10
011 2 = 0 10
010 2 = -1 10
001 2 = -2 10
000 2 = -3 10
<强>其他强>
还有其他更深奥的整数表示,例如平衡三元,基底负2或(可论证)二进制编码的十进制(或简称BCD)。我之所以说BCD是有争议的,是因为现代处理器通常仍然支持它(虽然它不是数字在内部表示的方式),并且许多计算器过去都是以它为基础的。在这些系统中,前导位(或trit或base-n数字)可能表示或可能不表示符号(或者在某些情况下可能表示符号而不是其他情况)。
&#34;最终用户如何确定11101100与236和-20之间的差异?&#34;
正如其他人所指出的那样,通常无法判断存储在寄存器或存储器中的数字是否实际上是2s补码或无符号。你基本上必须跟踪它做了什么来确定它。
但是,如果该数字是直接存储在机器代码指令中的值,则操作码可以指示它是否已签名(取决于体系结构)。例如,这可能会改变溢出的处理方式,或者是否执行 sign-extension 。
例如,可能会有单独的&#34;立即加载&#34;和#34;立即加载签名&#34;将立即值值复制到较大寄存器的指令,第二个执行符号扩展,第一个不执行。 &#34;科&#34;指令通常具有签名立即数以指示跳转的大小(以便前向和后向分支都可以使用单个指令)。可能会有不同的&#34;立即添加&#34;并且&#34;添加unsigned immediate&#34;适用于添加类型的溢出标志的指令。
签署扩展程序
符号扩展意味着复制高位以保留2s补码的值。对于无符号数的一半,这将产生不正确的结果。
未执行签名扩展:
100 2 = 00000100 2
无符号:4 10 = 4 10
签名:-4 10 = 4 10
执行签名扩展:
100 2 = 11111100 2
签名:-4 10 = -4 10
无符号:4 10 = 252 10001 2 = 00000001 2
有符号和无符号:1 10 = 1 10
<强>溢出强>
添加或减去两个数字可能会给出一个太大(绝对意义上)正确表示的结果。添加相同的两个二进制序列可能会导致有符号数的溢出,但不会导致无符号(或反之亦然)。
有符号溢出但无符号不会:
011 2 + 011 2 = 110 2
签名:3 10 +3 10 = -2 10
无符号:3 10 +3 10 = 6 10
无符号溢出但签名不符合:
111 2 + 010 2 = 001 2
无符号:7 10 + 2 10 = 1 10
签名:-1 10 + 2 10 = 1 10
答案 1 :(得分:4)
在二进制补码表示法中,最高位始终表示符号。但是,您必须知道字段宽度,并且还必须知道是否正在使用两个补码表示法。例如,如果11101100是32位数,则最高有效位为0,因此它为+236。如果它是无符号 8位整数,则为+236,因为无符号数不使用二进制补码表示法(只有有符号数)。
在二进制文件中添加和减去是计算机的工作方式。因此,了解计算机的工作原理非常有用。
答案 2 :(得分:3)
最终用户如何确定11101100之间的差异 236和-20?
用户无法单独从位模式确定它。某些上下文必须指出此字节是有符号还是无符号。在大多数编程语言中,通过跟踪类型来跟踪此上下文。因此,在C或C ++中,您有signed char
和unsigned char
。 (普通的旧char
可以是其中之一。)
有理由二进制减法的工作原理是它(就像其他一些操作一样)恰好与位模式完全相同,即使你输入的类型是“错误的”。想到这一点的一种方法是(对于这些操作)你正在做算术模256,并且模数236和-20实际上是两个相同数字的名称。
答案 3 :(得分:1)
简短的回答是,这取决于你如何使用它。几乎所有的现代编译器都将它们的整数值表示为两个恭维。这是一个惯例。如果您在汇编中编写代码,则必须更加关注内存或寄存器中的内容,但在更高级别的语言中,值的数据类型会告诉您。如果类型是有符号的,则MSB是符号位,否则不是。数据类型还告诉您该值中有多少位,因此您将能够识别哪个位是MSB。例如,int8_t总是8位并且是有符号的,而uint8_t总是8位但是是无符号的。只要你知道如何识别数据类型,当你看到它以二进制表示时,你就知道如何解释内存中的值。