题
在一个TC ++编译器,的二进制表示的 5 强>是<强>(00000000000000101)即可。 我知道负数被存储为2的补码,从而<强> -5 强>二进制是的(111111111111011)即可。最显著位(符号位)是1,它告诉它是一个负数。
那么,如何编译器知道它是 -5 ?如果我们解释上面给出的二进制值的(111111111111011)强>为一个无符号数,它会变成完全不同的?
另外,为什么是的1的补码的 5 强>的 -6(1111111111111010)强>
解决方案
<强>编译器不知道即可。如果你投-5
到unsigned int
你会得到32763
。
其他提示
编译器知道,因为这是CPU使用本身的惯例。您的电脑有在二进制补码存储负数的CPU,所以编译器跟风。如果你的CPU支持一个补码,编译器会使用(如与IEEE浮动的情况下,顺便说一句)。
在话题的维基百科的文章解释了如何补符号的作品。
该处理器执行符号和无符号的指令,这将在二进制数表示不同地操作。编译器知道这些这些指令来发出基于所涉及的操作数(即对int
unsigned int
)的类型。
编译器不需要知道一个数是否为负数或不是,它简单地发出用于所涉及的类型的正确的机器或中间语言指令。处理器或运行时的执行这些指令通常并不很担心,如果数字是负数,或者不要么,两个码算术运算的配方是这样的,它是正数或负数一样(其实,这是主要的优势二补运算)。什么的 的需要知道,如果一个数字是负数,会是这样的printf()
,和安德鲁谢斐指出,所设置的最高位是补指示负数的。
在第一个比特被设为仅对于负数(它被称为符号位)
的详细信息可这里
补的KEWL的部分是机器语言加法和减法指令可以忽略这一切,只是做算术,它只是作品...
即,-3 + 4
在二进制补码,是
1111 1111 1111 1101 (-3)
+ 0000 0000 0000 0100 ( 4)
-------------------
0000 0000 0000 0001 ( 1)
让我们举一个例子: 我们必须以二进制的两个字节两个数字: A = 10010111 B = 00100110 (注意,该机器不知道的概念在此电平符号或无符号)
现在,当你说“添加”这两个,什么是机?它只是增加了:
R = 10111101(和进位:1)
现在,我们 - 作为反编译需要解释的操作。我们有两个选择:在数字可以有符号或无符号的
。1-无符号的情况下:在C中,数字是类型“无符号字符”,值是151和38,其结果是这189.是微不足道的
。2 - 签署情况下:我们,编译器,根据它们的MSB和所述第一数量解释的数字是-105,第二个是38,仍然如此-105 + 38 = -67。但-67是10111101,但是这是我们已经有了结果(R)!其结果是一样的,唯一的区别是编译器如何解释它。
结论是,无论我们如何考虑号码,机器不上的数字相同的操作。但是,编译器会解释反过来的结果。
请注意,这不是谁知道2的补数的概念机。它只是增加了两个数字而无需关心内容。的编译器,然后,着眼于符号位和决定强>
当涉及到减法,再次此时,操作独特:取2的所述第二数量的补体和添加两个。
如果数量被声明为签名数据类型(和不类型转换为一个无符号的类型),则编译器将知道的是,当符号位是1,这是一个负数。至于为什么2的补数将使用1的补,而不是,你不希望能有-0的值,其中1的补会允许你这样做,于是他们发明2的补修理好了。
这正是大多数显著位 - 如果你知道一个数字签名,则如果MSB = 1编译器(和运行!)知道把它解释为负。这就是为什么类似C语言有两个整数(正面和负面的)和无符号整数 - 在这种情况下,你解释他们都为阳性。因此,一个符号的字节去从-128到127,而是从0到255的无符号字节。