2015-04-28 63 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表示。