0

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

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

另外,为什么 1 是5 -6 (1111111111111010)的补码?

4

8 回答 8

8

编译器不知道。如果你投到-5unsigned int会得到32763.

于 2009-03-17T17:34:31.480 回答
5

编译器知道,因为这是 CPU 原生使用的约定。您的计算机有一个 CPU,它以二进制补码表示法存储负数,因此编译器也会效仿。如果您的 CPU 支持一个补码表示法,编译器将使用它(顺便说一下,IEEE 浮点数就是这种情况)。

有关该主题的 Wikipedia 文章解释了二进制补码符号的工作原理。

于 2009-03-17T17:35:51.400 回答
3

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

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

于 2009-03-17T17:36:07.250 回答
2

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

详细信息可在此处获得

于 2009-03-17T17:31:55.963 回答
2

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

即,-3 + 4

在二进制 2 的补码中,是

   1111 1111 1111 1101   (-3)
+  0000 0000 0000 0100   ( 4)
   -------------------
   0000 0000 0000 0001   ( 1)
于 2009-03-17T17:40:54.960 回答
2

举个例子:我们在二进制的两个字节中有两个数字:A = 10010111 B = 00100110(注意机器不知道这个级别有符号或无符号的概念)

现在当您说“添加”这两个时,机器是什么?它只是添加:

R = 10111101(和进位位:1)

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

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

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

结论是,无论我们如何考虑数字,机器都会对数字进行相同的操作。但是编译器会依次解释结果。

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

When it comes to subtraction, this time again, the operation is unique: take 2's complement of the second number and add the two.

于 2010-12-03T09:49:17.253 回答
1

如果该数字被声明为有符号数据类型(而不是类型转换为无符号类型),那么编译器将知道,当符号位为 1 时,它是一个负数。至于为什么使用 2 的补码而不是 1 的补码,您不希望能够具有 -0 的值,而 1 的补码允许您这样做,所以他们发明了 2 的补码来解决这个问题。

于 2009-03-17T17:35:37.220 回答
0

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

于 2009-03-17T17:32:39.440 回答