Как обнаружить переполнение целого числа
Короткий ответ
Обычные операции молча «заворачивают» результат через границу. Методы Math.addExact(), multiplyExact() и подобные выбрасывают исключение:
void main() {
int max = Integer.MAX_VALUE;
IO.println(max + 1);
IO.println(Math.addExact(max, 1));
}Результат:
-2147483648
Exception in thread "main" java.lang.ArithmeticException: integer overflowПерехватить переполнение
Перехватите ArithmeticException, чтобы обработать ситуацию:
void main() {
int items = 70_000;
int price = 40_000;
try {
IO.println(Math.multiplyExact(items, price));
} catch (ArithmeticException e) {
IO.println("Too large: " + e.getMessage());
}
}Результат:
Too large: integer overflowСчитать в long
Часто достаточно выполнить вычисление в long. Приведите хотя бы один операнд к long до умножения:
void main() {
int items = 70_000;
int price = 40_000;
long total = (long) items * price;
IO.println(total);
}Результат:
2800000000Частая ошибка
Привести к long уже результат. Умножение выполнилось в int и переполнилось раньше, чем значение попало в long:
void main() {
int items = 70_000;
int price = 40_000;
long wrong = (long) (items * price);
IO.println(wrong);
}Результат:
-1494967296Функции из этого ответа
- ArithmeticException — Возникает при недопустимой арифметической операции, например целочисленном делении на ноль.
- Integer.MAX_VALUE — Наибольшее значение типа int; рядом — Integer.MIN_VALUE.