Используя Гуава , это так же просто, как
long c = LongMath.checkedAdd(a, b); // throws an ArithmeticException on overflow
, что, на мой взгляд, действительно очень читабельно.(LongMath Javadoc здесь .)
Ради справедливости, я упомяну, что Apache Commons предоставляет ArithmeticUtils.addAndCheck(long, long)
.
Если выхотите знать, как они работают, ну, ответ - одна строка хакерства для Guava: результат не переполняется, если (a ^ b) < 0 | (a ^ (a + b)) >= 0
.Это основано на уловке, что битовое XOR двух чисел неотрицательно, если они имеют один и тот же знак.
Так что (a ^ b) < 0
верно, если a
и b
имеют разные знаки, и если этона случай, если он никогда не переполнится.Или, если (a ^ (a + b)) >= 0
, то a + b
имеет тот же знак, что и a
, поэтому он не переполняется и не становится отрицательным.
(Чтобы узнать больше подобных уловок, изучите прекрасную книгу Восторг Хакера .)
В Apache используется более сложная тематическая работа, основанная на знаках a
и b
.