Если он переполняется, он возвращается к минимальному значению и продолжается оттуда. Если он переполняется, он возвращается к максимальному значению и продолжается оттуда.
Вы можете проверить это заранее следующим образом:
public static boolean willAdditionOverflow(int left, int right) {
if (right < 0 && right != Integer.MIN_VALUE) {
return willSubtractionOverflow(left, -right);
} else {
return (~(left ^ right) & (left ^ (left + right))) < 0;
}
}
public static boolean willSubtractionOverflow(int left, int right) {
if (right < 0) {
return willAdditionOverflow(left, -right);
} else {
return ((left ^ right) & (left ^ (left - right))) < 0;
}
}
(вы можете заменить int
на long
, чтобы выполнить те же проверки для long
)
Если вы считаете, что это может произойти более чем часто, тогда рассмотрите использование типа данных или объект, который может хранить большие значения, например long
или, возможно, java.math.BigInteger
.
Если вы уже на Java8 уже, то вы можете использовать новый Math#addExact()
и Math#subtractExact()
, которые будут перебрасывать ArithmeticException
при переполнении.
public static boolean willAdditionOverflow(int left, int right) {
try {
Math.addExact(left, right);
return false;
} catch (ArithmeticException e) {
return true;
}
}
public static boolean willSubtractionOverflow(int left, int right) {
try {
Math.subtractExact(left, right);
return false;
} catch (ArithmeticException e) {
return true;
}
}
Исходный код можно найти здесь здесь и здесь соответственно.
Конечно, вы могли бы просто использовать их прямо сейчас, а не прятать их в утилите boolean
.