了解整数范围

时间:2016-02-22 21:01:55

标签: java

我正在教授AP Comp Science,我无法找到一种简单的方法来解释学生如何回答这个Java问题。理解答案是一回事,向学生解释如何在有限的时间内回答答案。

    int sum = 0, p = 1;
    for (int count = 1; count <= 50; count++)
    {
         sum += p;
         p *= 2;  
    } 
    System.out.println(sum);

哦,是的,答案是-1。

2 个答案:

答案 0 :(得分:2)

我理解它的方式,当我阅读你的代码时,-1的二进制补码二进制表示都是1,这正是你的代码构建的:它相当于(简化为假装四位类型):

 0001
+0010
+0100
+1000
+0000 // overflow hits here
-----
 1111 // the binary representation of -1

...并且-1的二进制表示是全1的原因是,继续我们假装的四位整数类型,

abcd = a * -2^3 + b * 2^2 + c * 2^1 + d * 2^0

...注意到两个补码的工作方式是第一位 - 最高位,a在这里 - 它的符号被交换;它乘以-2 ^ 3而不是2 ^ 3。所以1111是-8 + 4 + 2 + 1 = -8 + 7 = -1。

答案 1 :(得分:2)

如果您将代码更改为以下内容:

int sum = 0, p = 1;
for (int count = 1; count <= 32; count++) {
    sum += p;
    p *= 2;
    System.out.printf("%-10s = %s%n", sum, Integer.toBinaryString(sum));
}

我已经将循环大小缩小到32,因为那是必需的。

然后输出变为:

1          = 1
3          = 11
7          = 111
15         = 1111
31         = 11111
63         = 111111
127        = 1111111
255        = 11111111
511        = 111111111
1023       = 1111111111
2047       = 11111111111
4095       = 111111111111
8191       = 1111111111111
16383      = 11111111111111
32767      = 111111111111111
65535      = 1111111111111111
131071     = 11111111111111111
262143     = 111111111111111111
524287     = 1111111111111111111
1048575    = 11111111111111111111
2097151    = 111111111111111111111
4194303    = 1111111111111111111111
8388607    = 11111111111111111111111
16777215   = 111111111111111111111111
33554431   = 1111111111111111111111111
67108863   = 11111111111111111111111111
134217727  = 111111111111111111111111111
268435455  = 1111111111111111111111111111
536870911  = 11111111111111111111111111111
1073741823 = 111111111111111111111111111111
2147483647 = 1111111111111111111111111111111
-1         = 11111111111111111111111111111111

这变得更加清晰。您每次p乘以2,并将其添加到sum

这类似于bitshift操作,即每次向二进制表示添加一个1

int有32位空间 - 最终耗尽空间,并“溢出”。在Java中,int是二进制补码表示,因此当符号位溢出时,int变为负数。