[英]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 也会是100
或010
谢谢
你对这些负数应该是什么样子的理解是有缺陷的。 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.