Что такое переполнение (overflow/underflow) целочисленного типа int в Java?

Ответ

Переполнение целочисленного типа int в Java происходит, когда результат арифметической операции выходит за пределы его допустимого диапазона.

Тип int в Java является 32-битным знаковым целым числом. Его диапазон фиксирован:

  • Минимальное значение: Integer.MIN_VALUE = -2,147,483,648
  • Максимальное значение: Integer.MAX_VALUE = 2,147,483,647

При переполнении значение не вызывает исключения, а "заворачивается" (wrap-around) по модулю 2^32, переходя от максимума к минимуму или наоборот.

Примеры переполнения:

// Переполнение (overflow)
int max = Integer.MAX_VALUE;
System.out.println(max);       // 2147483647
System.out.println(max + 1);   // -2147483648 (Integer.MIN_VALUE)

// Антипереполнение (underflow)
int min = Integer.MIN_VALUE;
System.out.println(min);       // -2147483648
System.out.println(min - 1);   // 2147483647 (Integer.MAX_VALUE)

Как предотвратить:

  1. Использовать тип long (64-битный), если ожидаются большие числа.
  2. Использовать Math.addExact(), Math.multiplyExact() — эти методы выбрасывают ArithmeticException при переполнении.
    try {
        int safeResult = Math.addExact(Integer.MAX_VALUE, 1);
    } catch (ArithmeticException e) {
        System.out.println("Переполнение!");
    }
  3. Использовать BigInteger для операций с произвольно большими целыми числами.

Ответ 18+ 🔞

А, слушай, вот эта тема про переполнение int в Java — это просто классика, блядь! Прямо как Герасим с Муму, только с числами. Сидит себе тихонечко int, в своём диапазоне, а потом — хрясь! — и пиздец, значение в минус улетело.

Короче, смотри. Этот int — он как немой крестьянин, сил дохуя, а места мало. Всего-то 32 бита ему выделили, жмоты, сука. И живёт он в строгих рамках:

  • Снизу: -2 147 483 648 (это Integer.MIN_VALUE, его личный ад)
  • Сверху: 2 147 483 647 (это Integer.MAX_VALUE, его потолок, блядь).

И вот представь, он доходит до этого потолка, а ты ему: «Ну-ка, прибавь ещё единичку!». А он, сука, нихуя не орёт, как Герасим, исключение не кидает. Он просто берёт и... перепрыгивает через потолок прямиком в подвал, к минимальному значению! Это и есть переполнение, ёпта. Обратный процесс — антипереполнение — это когда из подвала вычитаешь и выскакиваешь на чердак.

// Вот смотри, чистый маразм
int max = Integer.MAX_VALUE; // 2147483647, всё ок
System.out.println(max + 1); // -2147483648, пиздец! С максимума на минимум!

Вот так вот тихо и незаметно программа может наебнуться, а ты потом полдня ищешь, откуда хуйня в расчётах лезет. Волнение ебать!

Ну и как с этой поебенью бороться? Да элементарно!

  1. Использовать long. Это как дать Герасиму целое поле вместо конуры. Места завались, 64 бита. Пока допрыгаешь до его пределов — уже поумнеешь.
  2. Тырить методы Math. Есть же специальные штуки, которые не молчат, а орут при переполнении! Math.addExact(), Math.multiplyExact(). Они как разумный человек: видят, что щас пиздец настанет, и честно кидают ArithmeticException.
    try {
        int safeResult = Math.addExact(Integer.MAX_VALUE, 1); // Пытаемся наебать систему
    } catch (ArithmeticException e) {
        System.out.println("Переполнение, мудак!"); // А система нам: «Ага, щас!»
    }
  3. Взять BigInteger. Это уже полный отрыв, ядрёна вошь! Типа «похуй на размер, дайте мне ВСЕ ЦИФРЫ НА СВЕТЕ». Для расчётов, где числа больше, чем звёзд в хуёвой галактике.

Вот и вся философия. Главное — не надеяться, что int сам разберётся. Он, блядь, немой, он промолчит, а потом утопит твою программу, как Муму. Доверия к нему — ноль ебать.