繁体   English   中英

Java中负整数的二进制表示

[英]Binary presentation of negative integer in Java

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

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

据我所知 -5 的二进制表示应该是10000000.00000000.00000000.00000101

但输出是11111111.11111111.11111111.11111011

我有两个问题:

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

2)我真的无法理解最后3位011 它看起来像3 即使是 +1 或 -1 也会是100010

谢谢

你对这些负数应该是什么样子的理解是有缺陷的。 Java 对负数使用二进制补码,基本规则是取正数,反转所有位然后加一。 这让你感到消极。

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

0000...00000101

反转给你:

1111...11111010

然后添加一个给出:

1111...11111011

-5显示的位模式称为符号/幅度,您只需翻转最左边的位即可否定一个数字。 这在 C 实现中允许作为三种可能性(a) 之一,但 Java 仅使用二进制补码(对于其负整数)。


(a)但请记住,C 和 C++ 目前都在努力删除其他两种编码类型并只允许二进制补码。

据我所知 -5 的二进制表示应该是10000000.00000000.00000000.00000101

如果 Java 对整数使用Sign 和 Magnitude表示,那将是正确的。 但是,Java 使用Two's Complement表示法,因此其余位会根据该表示法的规则进行更改。

二进制补码表示背后的想法是,当您将这种表示中的一个数字与另一个值相加时,删除最高有效端的额外位,结果就好像您减去了相同数量级的正数。

你可以用十进制数来说明这一点。 在两位数表示中,值 99 的行为类似于 -1,98 的行为类似于 -2,97 的行为类似于 -3,依此类推。 例如,如果您删除23 + 99 = [1]22的最高数字,则 99 的行为类似于 -1。 23 + 98 = [1]21 ,所以 98 表现得像 -2。

这与二进制数的二进制补码表示方式相同,只是您将删除顶部的额外位。

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

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

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

这使得-1

在这种表示下,小的负数将主要是负数。

以下是 2 的赞美示例:

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

0000 0000 0000 0000 0000 0000 0001 1110

反转数字。

1111 1111 1111 1111 1111 1111 1110 0001

并加一个。

1111 1111 1111 1111 1111 1111 1110 0010

转换回十六进制,这是 0xFFFFFFE2。 事实上,假设你有这个代码:

#include <stdio.h>

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

    return 0;
}

那应该产生-30的输出。 喜欢就试试吧。

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

当我开始了解到数字的表示比 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