Java中负整数的二进制表示

Java中负整数的二进制表示,java,Java,请帮我理解负整数的二进制表示法 例如,我们有5个。 5的二进制表示形式是00000000.00000000.00000000.00000101 据我所知,-5的二进制表示应该类似于10000000.00000000.00000000.00000101 但输出是11111111.11111111.11111111.11111111.11111 011 我有两个问题: 1) 为什么这里有这么多1位 2) 我真正无法理解的是最后3位011。它看起来像3。即使是+1或-1,也将是100或010 谢谢你对

请帮我理解负整数的二进制表示法

例如,我们有5个。 5的二进制表示形式是
00000000.00000000.00000000.00000101

据我所知,-5的二进制表示应该类似于
10000000.00000000.00000000.00000101

但输出是
11111111.11111111.11111111.11111111.11111 011

我有两个问题:

1) 为什么这里有这么多
1

2) 我真正无法理解的是最后3位
011
。它看起来像
3
。即使是+1或-1,也将是
100
010


谢谢

你对这些负数应该是什么样子的理解是有缺陷的。Java对负数使用2的补码,基本规则是取正数,反转所有位,然后加一。这会给你带来负面影响

因此,正如你所说,五是:

0000...00000101
反转,使您:

1111...11111010
然后加上一个就可以得到:

1111...11111011
您为
-5
显示的位模式称为符号/幅度,您只需翻转最左边的位即可对数字求反。这在C实现中被允许作为(a)中的一个,但Java只使用2的补码(对于其负整数)


(a)但记住C和C++中目前的努力是去除其他两种编码类型,只允许两种补充。

负数的存储方式是将最高有效位(例如,对于32位数字,代表2^31的位)视为负数。所以,如果你存储了所有的1,你就可以加起来

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

在这种情况下,小负数将主要是负数

据我所知,-5的二进制表示应该类似于
10000000.00000000.00000000.00000101

如果Java使用整数的表示,这是正确的。但是,Java使用表示法,因此其余的位将根据该表示法的规则进行更改

2的补码表示法背后的思想是,当你把这种表示法中的一个数字加到另一个值上,去掉最有效端的额外位时,结果就好像你减去了一个大小相同的正数

你可以用十进制数字来说明这一点。在两位数表示法中,99的值的行为类似于-1,98的行为类似于-2,97的行为类似于-3,依此类推。例如,如果将顶部数字放在
23+99=[1]22
中,则99的行为类似于-1<代码>23+98=[1]21,因此98的行为类似于-2


这与二进制数的2的补码表示法的工作原理相同,只是您会将多余的位放在顶部。

下面是2的恭维示例:

如果您有-30,并且希望用2的补码表示它,则采用30的二进制表示:

0000 0000 0001 1110

颠倒数字

111111111111111111111111111111111111111010001

再加一个

1111111111111111111111111111111111111111110010

转换回十六进制,这是0xFFFFFF2。事实上,假设您有以下代码:

#include <stdio.h>

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

    return 0;
}
#包括
int main(){
int-myInt;
myInt=0xFFFFFF2;
printf(“%d\n”,myInt);
返回0;
}

这将产生-30的输出。如果您愿意,可以试试。

使用2的补码,MSB为1表示负数是正确的。但剩余的位不是其值的二进制表示。另一方面,如果MSB为0,则剩余的位表示二进制值。但当时不能说这个数字是正的。零既不是正也不是负

当我开始了解数字的表示形式比0..9更多时,这张图片帮助我理解了这一原理:

           0
    -1    000    1
       111   001  
-2  110         010  2
       101   011
    -3    100    3
          -4
请仔细阅读。