2015-04-28 2 views
1

Я учусь для моего выпускного экзамена в AP Computer Science, и я наткнулся на этот вопрос:Почему вывод этой программы -1?

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

Выход составляет -1; однако я не понимаю, почему это так. Если кто-то может объяснить это мне, это было бы потрясающе.

+4

[целочисленное переполнение] (http://en.wikipedia.org/wiki/Integer_overflow) – amit

ответ

6

Добавляя 1,2,4,8, ..., вы в основном заполняете двоичное представление sum с помощью 1-го.

С 111..1 является представительством -1, вы фактически генерируете это число.

Это часто рассматривается как Integer Overflow.

0

В дополнение к предыдущим ответам.

Целое число в java представлено 32 bits. Таким образом, легко видеть, что максимальное значение, которое может быть представлено с ИНТОМ:

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. Согласно Википедии, дополнение «Два» - это просто способ обеспечить:

«... положительные и отрицательные числа могут сосуществовать естественным образом».

2's Complement может преобразовать положительное целое число со знаком X, имеющее знак бит = 0, в отрицательный -X.

Например (используя 8 бит):

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

Чтобы получить представление -105, мы используем Complement Two, которая делается с помощью:

  1. Flipping все биты, так что 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 является числовой переменной со знаком. Как упоминалось в предыдущем ответе, программа заполняет 32 бита, выделенные для int sum с 1.

Вы можете увидеть это хорошо, если вы кладете в операторе печати, как этот 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, .... 

А если добавить, если заявление, чтобы поймать значение счетчика, когда сумма идет в -1, вы обнаружите, что он идет -1 вправо, когда счетчик = 32. Какой имеет смысл, учитывая факт, что после того, как вы запустили программу 1 в MSB или бите знака, 32-разрядное число ber рассматривается как отрицательное число.

Теперь, используя дополнение «Два», мы можем точно определить, что это за отрицательное число, используя тот факт, что вы можете не только получить отрицательное представление числа, но и получить положительное представление, если вам дали отрицательный результат номер. Таким образом, мы имеем:

  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 
    

Что представляет номер 1. Таким образом, мы видим, что 1111 1111 1111 1111 1111 1111 1111 1111 является представление -1.

Смежные вопросы