简体   繁体   English

二进制补码形式

[英]Two's complement binary form

In a TC++ compiler, the binary representation of 5 is (00000000000000101) .在 TC++ 编译器中, 5的二进制表示是(00000000000000101) I know that negative numbers are stored as 2's complement, thus -5 in binary is (111111111111011) .我知道负数存储为 2 的补码,因此二进制中的-5(111111111111011) The most significant bit (sign bit) is 1 which tells that it is a negative number.最高有效位(符号位)是 1,表示它是负数。

So how does the compiler know that it is -5 ?那么编译器如何知道它是-5呢? If we interpret the binary value given above (111111111111011) as an unsigned number, it will turn out completely different?如果我们将上面给出的二进制值(111111111111011)解释为无符号数,结果会完全不同吗?

Also, why is the 1's compliment of 5 -6 (1111111111111010) ?另外,为什么 1 是5 -6 (1111111111111010)的补码?

The compiler doesn't know .编译器不知道 If you cast -5 to unsigned int you'll get 32763 .如果您将-5转换为unsigned int ,您将得到32763

The compiler knows because this is the convention the CPU uses natively.编译器知道,因为这是 CPU 原生使用的约定。 Your computer has a CPU that stores negative numbers in two's complement notation, so the compiler follows suit.您的计算机有一个 CPU,它以二进制补码表示法存储负数,因此编译器也会效仿。 If your CPU supported one's complement notation, the compiler would use that (as is the case with IEEE floats, incidentally).如果您的 CPU 支持一个补码表示法,编译器将使用它(顺便说一下,IEEE 浮点数就是这种情况)。

The Wikipedia article on the topic explains how two's complement notation works.有关该主题的 Wikipedia 文章解释了二进制补码表示法的工作原理。

The processor implements signed and unsigned instructions, which will operate on the binary number representation differently.处理器实现有符号和无符号指令,它们将以不同的方式对二进制数表示进行操作。 The compiler knows which of these instructions to emit based on the type of the operands involved (ie int vs. unsigned int ).编译器根据所涉及的操作数的类型(即intunsigned int )知道要发出哪些指令。

The compiler doesn't need to know if a number is negative or not, it simply emits the correct machine or intermediate language instructions for the types involved.编译器不需要知道一个数字是否为负,它只是为所涉及的类型发出正确的机器或中间语言指令。 The processor or runtime's implementation of these instructions usually doesn't much care if the number is negative or not either, as the formulation of two's complement arithmetic is such that it is the same for positive or negative numbers (in fact, this is the chief advantage of two's complement arithmetic).这些指令的处理器或运行时的实现通常不太关心数字是否为负,因为二进制补码算术的公式对于正数或负数是相同的(事实上,这是主要的补码算法的优势)。 What would need to know if a number is negative would be something like printf() , and as Andrew Jaffe pointed out, the MSBit being set is indicative of a negative number in two's complement.需要知道一个数字是否为负数类似于printf() ,正如 Andrew Jaffe 指出的那样,设置的 MSBit 表示二进制补码中的负数。

let us give an example: we have two numbers in two bytes in binary: A = 10010111 B = 00100110 (note that the machine does not know the concept of signed or unsigned in this level)举个例子:我们在二进制的两个字节中有两个数字:A = 10010111 B = 00100110(注意机器不知道这个级别有符号或无符号的概念)

now when you say "add" these two, what does the machine?现在当您说“添加”这两个时,机器是什么? it simply adds:它只是添加:

R = 10111101 (and carry bit: 1) R = 10111101(和进位位:1)

now, we -as compiler- need to interpret the operation.现在,我们——作为编译器——需要解释这个操作。 we have two options: the numbers can be signed or unsigned.我们有两个选择:数字可以有符号或无符号。

1- unsigned case: in c, the numbers are of type "unsigned char" and the values are 151 and 38 and the result is 189. this is trivial. 1- 无符号情况:在 c 中,数字的类型为“无符号字符”,值为 151 和 38,结果为 189。这是微不足道的。

2 - signed case: we, the compiler, interpret the numbers according to their msb and the first number is -105 and the second is still 38. so -105 + 38 = -67. 2 - 带符号的情况:我们,编译器,根据它们的 msb 解释数字,第一个数字是 -105,第二个数字仍然是 38。所以 -105 + 38 = -67。 But -67 is 10111101. But this is what we already have in the result (R), The result is same.但是-67是10111101。但是这是我们已经在结果(R)中得到的,结果是一样的。 the only difference is how the compiler interprets it.唯一的区别是编译器如何解释它。

The conclusion is that, no matter how we consider the numbers, the machine does the same operation on the numbers.结论是,无论我们如何考虑数字,机器都会对数字进行相同的操作。 But the compiler will interpret the results in its turn.但是编译器会依次解释结果。

Note that, it is not the machine who knows the concept of 2's complement .请注意,不是机器知道 2 的补码的概念 it just adds two numbers without caring the content.它只是添加两个数字而不关心内容。 The compiler , then, looks at the sign bit and decides .然后,编译器查看符号位并决定.

When it comes to subtraction, this time again, the operation is unique: take 2's complement of the second number and add the two.当涉及到减法时,这一次,操作是独特的:取第二个数的 2 的补码,然后将两个数相加。

The first bit is set only for negative numbers (it's called the sign bit)第一位仅为负数设置(称为符号位)

Detailed information is available here详细信息可在此处获得

The kewl part of two's complement is that the machine language Add, and Subtract instructions can ignore all that, and just do binary arithmetic and it just works...二进制补码的kewl部分是机器语言加法和减法指令可以忽略所有这些,只做二进制算术,它就可以工作......

ie, -3 + 4即,-3 + 4

in Binary 2's complement, is在二进制 2 的补码中,是

   1111 1111 1111 1101   (-3)
+  0000 0000 0000 0100   ( 4)
   -------------------
   0000 0000 0000 0001   ( 1)

If the number is declared as a signed data type (and not type cast to an unsigned type), then the compiler will know that, when the sign bit is 1, it's a negative number.如果该数字被声明为有符号数据类型(而不是类型转换为无符号类型),那么编译器将知道,当符号位为 1 时,它是一个负数。 As for why 2's complement is used instead of 1's complement, you don't want to be able to have a value of -0, which 1's complement would allow you to do, so they invented 2's complement to fix that.至于为什么使用 2 的补码而不是 1 的补码,您不希望能够具有 -0 的值,而 1 的补码可以让您这样做,所以他们发明了 2 的补码来解决这个问题。

It's exactly that most significant bit -- if you know a number is signed, then if the MSB=1 the compiler (and the runtime.) knows to interpret it as negative.这正是最重要的位——如果你知道一个数字是有符号的,那么如果 MSB=1,编译器(和运行时)知道将其解释为负数。 This is why c-like languages have both integers (positive and negative) and unsigned integers -- in that case you interpret them all as positive, Hence a signed byte goes from -128 to 127. but an unsigned byte from 0 to 255.这就是为什么类 c 语言同时具有整数(正数和负数)和无符号整数的原因——在这种情况下,您将它们都解释为正数,因此有符号字节从 -128 到 127。但无符号字节从 0 到 255。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM