Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 两个';s补码二进制形式_C++_Binary_Twos Complement - Fatal编程技术网

C++ 两个';s补码二进制形式

C++ 两个';s补码二进制形式,c++,binary,twos-complement,C++,Binary,Twos Complement,在TC++编译器中,5的二进制表示形式是(000000000000001)。 我知道负数存储为2的补码,因此二进制中的-5是(111111111011)。最高有效位(符号位)是1,表示它是一个负数 那么编译器如何知道它是-5?如果我们将上面给出的二进制值(111111111011)解释为无符号数,结果会完全不同吗 另外,为什么1对5-6(1111111111010)的赞美?第一位仅为负数设置(称为符号位) 详细信息是可用的这正是最重要的位——如果知道一个数字是有符号的,那么如果MSB=1,编译器

在TC++编译器中,5的二进制表示形式是(000000000000001)。 我知道负数存储为2的补码,因此二进制中的-5(111111111011)。最高有效位(符号位)是1,表示它是一个负数

那么编译器如何知道它是-5?如果我们将上面给出的二进制值(111111111011)解释为无符号数,结果会完全不同吗


另外,为什么1对5-6(1111111111010)的赞美?

第一位仅为负数设置(称为符号位)


详细信息是可用的

这正是最重要的位——如果知道一个数字是有符号的,那么如果MSB=1,编译器(和运行时!)知道将其解释为负数。这就是为什么类c语言同时具有整数(正整数和负整数)和无符号整数的原因——在这种情况下,您将它们都解释为正整数。因此,有符号字节从-128变为127,而无符号字节从0变为255。

编译器不知道。如果将
-5
转换为
无符号int
则会得到
32763
如果数字声明为有符号数据类型(而不是类型转换为无符号类型),则编译器将知道,当符号位为1时,它是负数。至于为什么使用2的补码而不是1的补码,您不想让值为-0,1的补码允许您这样做,所以他们发明了2的补码来解决这个问题。

编译器知道,因为这是CPU本机使用的约定。您的计算机有一个CPU,它以2的补码表示法存储负数,因此编译器也会这样做。如果您的CPU支持补码表示法,编译器将使用它(顺便说一句,IEEE浮点数就是这样)


Wikipedia关于该主题的文章解释了符号是如何工作的。

处理器实现有符号和无符号指令,这两种指令将以不同的方式对二进制数表示进行操作。编译器根据所涉及的操作数类型(即
int
unsigned int
)知道要发出哪些指令


编译器不需要知道一个数字是否为负数,它只是为所涉及的类型发出正确的机器或中间语言指令。处理器或运行时对这些指令的实现通常不太关心数字是否为负数,因为two的补码算法的公式对于正数或负数是相同的(事实上,这是two的补码算法的主要优点)。如果一个数字是负数,需要知道的是类似于
printf()
,正如Andrew Jaffe指出的,设置的MSBit表示2的补码中有负数。

2的补码的kewl部分是机器语言的加法和减法指令可以忽略所有这些,只要做二进制算术,它就行了

i、 e.,-3+4

在二进制2的补码中,是

   1111 1111 1111 1101   (-3)
+  0000 0000 0000 0100   ( 4)
   -------------------
   0000 0000 0000 0001   ( 1)
让我们举一个例子: 我们有两个二进制的两字节数字: A=10010111 B=00110 (请注意,机器不知道此级别中有符号或无符号的概念)

现在,当你说“添加”这两个时,机器会做什么?它只是补充说:

R=10111101(进位:1)

现在,作为编译器,我们需要解释这个操作。我们有两种选择:数字可以是有符号的,也可以是无符号的

1-无符号情况:在c中,数字类型为“unsigned char”,值为151和38,结果为189。这是微不足道的

2-符号大小写:我们,编译器,根据它们的msb解释数字,第一个数字是-105,第二个仍然是38。所以-105+38=-67。但是-67是10111101。但这是我们在结果(R)中已经得到的!结果是一样的,唯一的区别是编译器如何解释它

结论是,不管我们如何考虑数字,机器在数字上做同样的运算。但编译器将依次解释结果

请注意,知道2的补码概念的不是机器。它只添加两个数字,而不关心内容编译器然后查看符号位并决定


当谈到减法时,这一次,操作是独特的:取第二个数字的2的补码,然后将两个相加

实际上,一个带符号的字节从-128变为127。+1:引用一些有用的文档+1:是硬件+1:编译器对这个数字一无所知——你声明它是有符号的还是无符号的——然后你必须将它与声明一致地使用。你知道,我完全忘记了2的补码属性。这可能是它被发明的另一个很好的原因。如果我写
signed int a=-1
,那么
-1
以2的补码形式是
11111111111111111111111111
,然后当我用%d解释它时,它打印-1和%u,它打印
4294967295
,当我写signed int a=2,当我使用
%d
%u
时,它会打印2。如果2在2的补码中,它将是
11111111111111111111111111111111101
,然后它将是一个非常不同的答案,我真正想问的是2的补码何时发生,它依赖于符号,或者如果类型是有符号的int,它发生在每个整数上,这里肯定不是这样的。是的,强制转换告诉编译器如何解释特定内存位置的位。一般来说,它对什么东西在哪里有自己的想法,但是一个演员会把事情弄得一团糟