Почему переполнение Java возвращает 0 в качестве значения - PullRequest
1 голос
/ 13 октября 2019

У меня есть следующий фрагмент кода

public class DN1{
  public static void main(String argv[]){
    int a = 869;
    int b = 85;
    for(int i = 0; i < a; i++){
      b += b;
    }
    System.out.println(b);
  }
}

Этот код явно переполняется при i = 24

Мне было интересно, почему после пары циклов b устанавливается в 0. Что это за поведение переполнения и как именно оно работает в Java?

Я ожидал, что результат будет переменным между -2^31 to +2^31, но это не так, почему это так?

Ответы [ 2 ]

2 голосов
/ 13 октября 2019

Точнее, выходной сигнал находится в указанном вами диапазоне. 0 квалифицируется как находящийся между Integer.MIN_VALUE и Integer.MAX_VALUE.

Немного изменив свой код, вы можете взглянуть на происходящее и распечатать действительный двоичный файл

int a = 869;
int b = 85;
for(int i = 0; i < a; i++){
    System.out.printf(
            "Iteration %d: b = %d; b+b = %d; bin(b) = %s; bin(b+b) = %s%n",
            i, b, (b+b), Integer.toBinaryString(b), Integer.toBinaryString(b+b));
            b += b;
}
System.out.println(b);

, который дает следующий вывод

Iteration 0: b = 85; b+b = 170; bin(b) = 1010101; bin(b+b) = 10101010
Iteration 1: b = 170; b+b = 340; bin(b) = 10101010; bin(b+b) = 101010100
Iteration 2: b = 340; b+b = 680; bin(b) = 101010100; bin(b+b) = 1010101000
Iteration 3: b = 680; b+b = 1360; bin(b) = 1010101000; bin(b+b) = 10101010000
Iteration 4: b = 1360; b+b = 2720; bin(b) = 10101010000; bin(b+b) = 101010100000
Iteration 5: b = 2720; b+b = 5440; bin(b) = 101010100000; bin(b+b) = 1010101000000
Iteration 6: b = 5440; b+b = 10880; bin(b) = 1010101000000; bin(b+b) = 10101010000000
Iteration 7: b = 10880; b+b = 21760; bin(b) = 10101010000000; bin(b+b) = 101010100000000
Iteration 8: b = 21760; b+b = 43520; bin(b) = 101010100000000; bin(b+b) = 1010101000000000
Iteration 9: b = 43520; b+b = 87040; bin(b) = 1010101000000000; bin(b+b) = 10101010000000000
Iteration 10: b = 87040; b+b = 174080; bin(b) = 10101010000000000; bin(b+b) = 101010100000000000
Iteration 11: b = 174080; b+b = 348160; bin(b) = 101010100000000000; bin(b+b) = 1010101000000000000
Iteration 12: b = 348160; b+b = 696320; bin(b) = 1010101000000000000; bin(b+b) = 10101010000000000000
Iteration 13: b = 696320; b+b = 1392640; bin(b) = 10101010000000000000; bin(b+b) = 101010100000000000000
Iteration 14: b = 1392640; b+b = 2785280; bin(b) = 101010100000000000000; bin(b+b) = 1010101000000000000000
Iteration 15: b = 2785280; b+b = 5570560; bin(b) = 1010101000000000000000; bin(b+b) = 10101010000000000000000
Iteration 16: b = 5570560; b+b = 11141120; bin(b) = 10101010000000000000000; bin(b+b) = 101010100000000000000000
Iteration 17: b = 11141120; b+b = 22282240; bin(b) = 101010100000000000000000; bin(b+b) = 1010101000000000000000000
Iteration 18: b = 22282240; b+b = 44564480; bin(b) = 1010101000000000000000000; bin(b+b) = 10101010000000000000000000
Iteration 19: b = 44564480; b+b = 89128960; bin(b) = 10101010000000000000000000; bin(b+b) = 101010100000000000000000000
Iteration 20: b = 89128960; b+b = 178257920; bin(b) = 101010100000000000000000000; bin(b+b) = 1010101000000000000000000000
Iteration 21: b = 178257920; b+b = 356515840; bin(b) = 1010101000000000000000000000; bin(b+b) = 10101010000000000000000000000
Iteration 22: b = 356515840; b+b = 713031680; bin(b) = 10101010000000000000000000000; bin(b+b) = 101010100000000000000000000000
Iteration 23: b = 713031680; b+b = 1426063360; bin(b) = 101010100000000000000000000000; bin(b+b) = 1010101000000000000000000000000
Iteration 24: b = 1426063360; b+b = -1442840576; bin(b) = 1010101000000000000000000000000; bin(b+b) = 10101010000000000000000000000000
Iteration 25: b = -1442840576; b+b = 1409286144; bin(b) = 10101010000000000000000000000000; bin(b+b) = 1010100000000000000000000000000
Iteration 26: b = 1409286144; b+b = -1476395008; bin(b) = 1010100000000000000000000000000; bin(b+b) = 10101000000000000000000000000000
Iteration 27: b = -1476395008; b+b = 1342177280; bin(b) = 10101000000000000000000000000000; bin(b+b) = 1010000000000000000000000000000
Iteration 28: b = 1342177280; b+b = -1610612736; bin(b) = 1010000000000000000000000000000; bin(b+b) = 10100000000000000000000000000000
Iteration 29: b = -1610612736; b+b = 1073741824; bin(b) = 10100000000000000000000000000000; bin(b+b) = 1000000000000000000000000000000
Iteration 30: b = 1073741824; b+b = -2147483648; bin(b) = 1000000000000000000000000000000; bin(b+b) = 10000000000000000000000000000000
Iteration 31: b = -2147483648; b+b = 0; bin(b) = 10000000000000000000000000000000; bin(b+b) = 0

You 'по существу, сдвигая биты влево, логически эквивалентно умножению на 2 на каждой итерации. В результате вы получите двоичный код 10000000000000000000000000000000 на итерации 31, а сдвиг его влево вытолкнет 1 из последовательности, и вы останетесь с 00000000000000000000000000000000. Это происходит на итерации 31 независимо от вашего начального значения для b (у вас есть только 32 бита для работы, позиции 0-31).

Добавление: другие способы записи b += b:

b <<= 1
b *= 2
1 голос
/ 13 октября 2019

Просто добавьте оператор print внутри цикла for, что-то вроде следующего:

public static void main(String argv[]){
    int a = 869;
    int b = 85;
    for(int i = 0; i < a; i++){
      b += b;
      System.out.println(b);          <----- Add this to see 
    }
    System.out.println(b);
  }

Вывод:

170
340
680
1360
2720
5440
10880
21760
43520
87040
174080
348160
696320
1392640
2785280
5570560
11141120
22282240
44564480
89128960
178257920
356515840
713031680
1426063360
-1442840576
1409286144
-1476395008
1342177280
-1610612736
1073741824
-2147483648
0
0
0
0
0
0
.....

И так далее до конца цикла.

Обратите внимание, что установленный вами предел был пересечен слишком рано. Теперь причина, по которой вы видите 0 здесь и далее, заключается в том, что указана ссылка здесь и здесь

Обратите внимание на подробный ответ, т.е. Это поможет вам понять, почему он ведет себя так, как он себя ведет, и я думаю, что он не ограничивается только int, но также и в случае long, double и всеми другими numeric типами.

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...