2015-04-28 62 views
1

我学为我AP计算机科学期末考试,我碰到这个问题就来了:为什么这个程序的输出是-1?

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

输出为-1;但我不明白为什么会是这样。如果有人能向我解释这将是非常棒的。

+4

[integer overflow](http://en.wikipedia.org/wiki/Integer_overflow) – amit

回答

6

通过增加1,2,4,8,......,你基本上填补sum二进制表示与1的。

由于111..1-1表示,实际上产生此号码。

这往往被视为Integer Overflow

0

补充以前的答案。

Java中的整数由32 bits表示。因此,很容易看到,可以用一个int表示最大值为:

1111 1111 1111 1111 1111 1111 1111 1111 (which is 32 1's) 

,该值相当于:

(1)*2^0 + (1)*2^1 + (1)*2^2 + ... + (1)*2^31 = 2^32 - 1 = 4294967295 

但后来怎么整数表示负数?

答案是上述计算和限制仅适用于使用32位表示的无符号值。

负数用Sign Bit表示,其对应于最左边的位或MSB or Most Significant Bit

  • 如果符号位= 1,如在110中,数是负
  • 反之亦然

而且,由于该符号数需要一个位,以留出用于保持被设置的事实跟踪符号,有符号数字将永远不能表示大于无符号数字的数字,因为它们的位数较少。

即使知道MSB简直是符号值的符号位,我们如何找出实际数字是多少?

答案是使用Two's Complement。根据维基百科的说法,Two's Complement只是一种确保:

“......正数和负数可以自然方式共存。”

Two's Complement可以将符号位为0的正数有符号整数X转换为负-X。

例如(使用8位):

0110 1001 is the 2^0 + 2^3 + 2^5 + 2^6 = 105 

要获得-105表示,我们使用的补码,这是完成:

  1. 翻转所有位,所以0 - > 1和1 - > 0
  2. 添加一个到结果

因此,在我们的例子中,-105会由下式表示:

  1. 翻转所有的位,所以0 - > 1和1 - > 0

    0110 1001 -> 1001 0110 
    
  2. 添加一个到的结果。

    1001 0110 + 0000 0001 = 1001 0111 
    

因此我们得到1001 0111作为我们的-105

那么,如何这都涉及这个问题的代表性?

程序输出-1的原因是因为int是一个带符号的数字变量。正如前面提到的答案,该程序将填充为1的整数分配的32位。

,如果你把在打印语句,这样System.out.print(sum + ", ");打印出总和的值可以很好地看到这是循环的推移,你最后看到的是这样的:

1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535, 131071, 262143, 524287, 1048575, 2097151, 4194303, 8388607, 16777215, 33554431, 67108863, 134217727, 268435455, 536870911, 1073741823, 2147483647, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 

其中在二是:

1, 11, 111, 1111, 1 1111, .... 

如果你添加一个if语句时和去-1赶上计数的值,你会发现,它去为-1,权当数= 32。这是合理的,考虑到事实上,一旦你的程序在MSB或Sign Bit中填入1,那么32位数字ber被视为负数。

现在使用Two's Complement,我们可以利用这样一个事实确切知道负数是什么,不仅可以得到一个数的负表达式,而且如果给出一个负数,也可以得到正表示数。因此,我们有:

  1. 翻转所有的位,所以0 - > 1和1 - > 0

    1111 1111 1111 1111 1111 1111 1111 1111 -> 0000 0000 0000 0000 0000 0000 0000 0000 
    
  2. 添加一个到的结果。

    0000 0000 0000 0000 0000 0000 0000 0000 + 0001 = 0001 
    

代表的数量。因此,我们发现,1111 1111 1111 1111 1111 1111 1111 1111是-1表示。