请帮助我理解负整数的二进制表示。
例如我们有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
由于
答案 0 :(得分:12)
您对这些负数应该是什么样的理解是有缺陷的。 Java对负数使用两个补码,基本规则是取正数,反转所有位然后加1。这会让你感到消极。
因此,正如你所说:
0000...00000101
反过来给你:
1111...11111010
然后添加一个给出:
1111...11111011
你为-5
显示的位模式是什么叫做sign / magnitude,你可以通过翻转最左边的位来否定一个数字。这在C实现中被允许作为three possibilities之一,但Java仅使用两个补码(对于其负整数)。
答案 1 :(得分:2)
据我所知,-5的二进制表示应该像
10000000.00000000.00000000.00000101
。
如果Java对整数使用Sign and Magnitude表示,那将是正确的。但是,Java使用Two's Complement表示,因此其余位根据该表示的规则进行更改。
两个补码表示背后的想法是,当你在这样的表示中添加一个数字到另一个值时,在最重要的一端丢弃额外的位,结果就好像你减去了相同的正数一样大小
您可以用十进制数来说明这一点。在两位数表示中,99的值表现为-1,99表示-2,97表示-3,依此类推。例如,如果您删除23 + 99 = [1]22
中的顶部数字,那么99表现为-1。 23 + 98 = [1]21
,所以98表现得像-2。
这与二进制数的二进制补码表示方式相同,除了你将额外的位放在顶部。
答案 2 :(得分:0)
http://en.wikipedia.org/wiki/Two%27s_complement
存储负数的方式是最高有效位(例如,32位数表示2 ^ 31的位)被视为负数。因此,如果你存储了所有1,你会加起来
(-2^31) + 2^30 + 2^29 + ... + 2^1 + 2^0
使-1
。
在这种代表性下,小的负数将主要是那些。
答案 3 :(得分:0)
以下是2赞美的例子:
如果你有-30,并希望用2的补码表示,你可以采用30的二进制表示法:
<00> 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的输出。如果你愿意,可以尝试一下。
答案 4 :(得分:0)
使用2的补码,MSB为1表示负数。但其余的位不是其值的二进制表示。另一方面,如果MSB为0,则其余位表示二进制值。但不能说这个数字是积极的。零既不是正面也不是负面。
当我开始了解数字的表示多于0..9时,这张照片让我理解了原理:
0
-1 000 1
111 001
-2 110 010 2
101 011
-3 100 3
-4