Java的32位整数表示系统需要澄清吗?

时间:2013-12-26 20:17:31

标签: java integer bit-manipulation bit

我需要对Java中的十进制二进制表示(或任何其他语言)进行一些澄清。

请原谅,如果这太基础了,但我需要彻底了解它。

x = 31 is represented in Java 32 bit as:

x — > 00000000 00000000 00000000 00011111  // 

the binary to decimal conversion is achieved by:
                               2^4+2^3+2^2+2^1+2^0=31

现在,如果您考虑打开所有位,signed bit (most significant bit)除外,我们会得到

y -> 01111111 11111111 11111111 11111111

and binary to decimal conversion by summing powers of 2 will be:
        2^31+2^30………+2^3+2^2+2^1+2^0=4294967295.

但是,如果你这样做:

System.out.println(Integer.parseInt("1111111111111111111111111111111",2));
you get: 2147483647 which is 2^31-1

所以这意味着,当31 bits开启时,我没有得到2的幂的加法和。 这是为什么?

可能是我不明白的东西,如果有人可以澄清这将是非常有帮助的。

如果这有帮助: 所有这两个提升权力直到31都列在这个列表中:

[1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, 2147483648]
编辑:我更正了y - 表示,现在它有32位,但是如果你计算31位通过求和功能来打开,你会得到4294967295.我在python中有一个线程

>>> reduce(lambda x,y: x+y, [pow(2,i) for i in range(32)])
4294967295

3 个答案:

答案 0 :(得分:4)

问题在于:

y -> 011111111 11111111 11111111 11111111

and binary to decimal conversion by summing powers of 2 will be:
        2^31+2^30………+2^3+2^2+2^1+2^0=4294967295.
你已经放了一个太多的1。正如Jon Skeet在评论中提到的,你应该只有31个,而不是32个。因此,总和应该从2 ^ 30开始,而不是2 ^ 31。

更新:嗯,你已经更新了这一位,以获得正确数量的1。我对这笔金额的陈述仍然有效。它应该从2开始 30 ,而不是2 31

当你做这个部分时:

System.out.println(Integer.parseInt("1111111111111111111111111111111",2));
you get: 2147483647 which is 2^31-1

你有1的数字是正确的(31)。

答案 1 :(得分:3)

  

所以这意味着,当31位开启时,我没有得到2的幂的加法和。

是的,你得到2 0 + 2 1 + 2 2 + 2 3 +。 .. + 2 30 ...这是2 31 - 1,正如您所见。

添加2 31 ,因为它将由第32个1表示,此时你将超出限制int可以用Java表示。

考虑较小的数字可能更容易。假设你有5位 - 前面的例子:

Integer.parseInt("11111")

这将打印出31,正如您之前所说的那样......因为31是2 5 - 1。

因此,对于n位都设置为1,您得到2 n - 1 ...这对于31位的示例是正确的。这里没有任何不一致的地方。

答案 2 :(得分:3)

y -> 01111111 11111111 11111111 11111111
----------------------------------------
     31       23       15       7

该数字是每个字节中最高有效位的索引。

所以0x2^31 + 1x2^30 + 1x2^29 + ... + 1x2^0 = 2147483647

你只是走得太远了。

你可以实际测试这个

int a = 0b01111111_11111111_11111111_11111111;
System.out.println(a);

打印

2147483647