简体   繁体   English

Java中负整数的二进制表示

[英]Binary presentation of negative integer in Java

Please, help me to understand binary presentation of negative integers.请帮助我理解负整数的二进制表示。

For example we have 5. Binary presentation of 5 is 00000000.00000000.00000000.00000101 .例如,我们有 5。 5 的二进制表示是00000000.00000000.00000000.00000101

And as I understand binary presentation of -5 should be like 10000000.00000000.00000000.00000101 .据我所知 -5 的二进制表示应该是10000000.00000000.00000000.00000101

But output is 11111111.11111111.11111111.11111011 .但输出是11111111.11111111.11111111.11111011

I have 2 question:我有两个问题:

1) Why here is so much 1 bits. 1) 为什么这里有这么多1位。

2) What I really cant understand it last 3 bits 011 . 2)我真的无法理解最后3位011 It looks like 3 .它看起来像3 Even +1 or -1 it'll be 100 or 010即使是 +1 或 -1 也会是100010

Thanks谢谢

Your understanding of what those negative numbers should look like is flawed.你对这些负数应该是什么样子的理解是有缺陷的。 Java uses two's complement for negative numbers and the basic rule is to take the positive, invert all bits then add one. Java 对负数使用二进制补码,基本规则是取正数,反转所有位然后加一。 That gets you the negative.这让你感到消极。

Hence five is, as you state:因此,正如您所说,五是:

0000...00000101

Inverting that gives you:反转给你:

1111...11111010

Then adding one gives:然后添加一个给出:

1111...11111011

The bit pattern you have shown for -5 is what's called sign/magnitude, where you negate a number simply by flipping the leftmost bit.-5显示的位模式称为符号/幅度,您只需翻转最左边的位即可否定一个数字。 That's allowed in C implementations as one of the three possibilities (a) , but Java uses two's complement only (for its negative integers).这在 C 实现中允许作为三种可能性(a) 之一,但 Java 仅使用二进制补码(对于其负整数)。


(a) But keep in mind there are current efforts in both C and C++ to remove the other two encoding types and allow only two's complement. (a)但请记住,C 和 C++ 目前都在努力删除其他两种编码类型并只允许二进制补码。

And as I understand binary presentation of -5 should be like 10000000.00000000.00000000.00000101 .据我所知 -5 的二进制表示应该是10000000.00000000.00000000.00000101

That would be right if Java used a Sign and Magnitude representation for integers.如果 Java 对整数使用Sign 和 Magnitude表示,那将是正确的。 However, Java uses Two's Complement representation, so the rest of the bits are changed in accordance with the rules of that representation.但是,Java 使用Two's Complement表示法,因此其余位会根据该表示法的规则进行更改。

The idea behind two's complement representation is that when you add a number in such representation to another value dropping the extra bit on the most significant end, the result would be as if you subtracted a positive number of the same magnitude.二进制补码表示背后的想法是,当您将这种表示中的一个数字与另一个值相加时,删除最高有效端的额外位,结果就好像您减去了相同数量级的正数。

You can illustrate this with decimal numbers.你可以用十进制数来说明这一点。 In a two-digit representation, the value of 99 would behave like -1, 98 would be like -2, 97 like -3, and so on.在两位数表示中,值 99 的行为类似于 -1,98 的行为类似于 -2,97 的行为类似于 -3,依此类推。 For example, if you drop the top digit in 23 + 99 = [1]22 , so 99 behaved like -1.例如,如果您删除23 + 99 = [1]22的最高数字,则 99 的行为类似于 -1。 23 + 98 = [1]21 , so 98 behaved like -2. 23 + 98 = [1]21 ,所以 98 表现得像 -2。

This works the same way with two's complement representation of binary numbers, except you would drop the extra bit at the top.这与二进制数的二进制补码表示方式相同,只是您将删除顶部的额外位。

http://en.wikipedia.org/wiki/Two%27s_complement http://en.wikipedia.org/wiki/Two%27s_complement

The way negative numbers are stored is that the most significant bit (eg the bit representing 2^31 for a 32 bit number) is regarded as negative.负数的存储方式是最高有效位(例如,对于 32 位数字表示 2^31 的位)被视为负数。 So if you stored all 1s, you would add up所以如果你存储了所有的 1,你会加起来

(-2^31) + 2^30 + 2^29 + ... + 2^1 + 2^0

which makes -1 .这使得-1

Small negative numbers will be mostly ones under this representation.在这种表示下,小的负数将主要是负数。

Here is an example for 2's compliment:以下是 2 的赞美示例:

If you have -30, and want to represent it in 2's complement, you take the binary representation of 30:如果您有 -30,并且想用 2 的补码表示它,则采用 30 的二进制表示:

0000 0000 0000 0000 0000 0000 0001 1110 0000 0000 0000 0000 0000 0000 0001 1110

Invert the digits.反转数字。

1111 1111 1111 1111 1111 1111 1110 0001 1111 1111 1111 1111 1111 1111 1110 0001

And add one.并加一个。

1111 1111 1111 1111 1111 1111 1110 0010 1111 1111 1111 1111 1111 1111 1110 0010

Converted back into hex, this is 0xFFFFFFE2.转换回十六进制,这是 0xFFFFFFE2。 And indeed, suppose you have this code:事实上,假设你有这个代码:

#include <stdio.h>

int main() {
    int myInt;
    myInt = 0xFFFFFFE2;
    printf("%d\n",myInt);

    return 0;
}

That should yield an output of -30.那应该产生-30的输出。 Try it out if you like.喜欢就试试吧。

With two's complement it's true that a MSB of 1 indicates a negative number.对于二进制补码,MSB 为 1 表示负数是正确的。 But the remaining bits are not the binary representation of its value.但其余位不是其值的二进制表示。 On the other hand, if the MSB is 0 the remaining bits represent the binary value.另一方面,如果 MSB 为 0,则其余位表示二进制值。 But it cannot be said that the number is positive then.但不能说这个数字是正数。 Zero is neither positive nor negative.零既不是正也不是负。

This picture helped me to understand the principle when I started to learn that there are more representations of numbers than with 0..9:当我开始了解到数字的表示比 0..9 多时,这张图帮助我理解了原理:

           0
    -1    000    1
       111   001  
-2  110         010  2
       101   011
    -3    100    3
          -4

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

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