我正在教授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。
答案 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
变为负数。