patternjavaMajor
Int overflow check in Java
Viewed 0 times
overflowcheckintjava
Problem
I have a piece of code that takes a couple of integers and check if performing an addition on the inputs would result in an overflow.
I was wondering if this code is SOLID:
Does anyone have a better (faster) way to achieve the same thing?
I was wondering if this code is SOLID:
public static boolean CanAdd(int me, int... args) {
int total = me;
for (int arg : args) {
if (total >= 0) {
if (java.lang.Integer.MAX_VALUE - total >= arg) { // since total is positive, (MaxValue - total) will never overflow
total += arg;
} else {
return false;
}
} else {
if (java.lang.Integer.MIN_VALUE- total <= arg) { // same logic as above
total += arg;
} else {
return false;
}
}
}
return true;
}Does anyone have a better (faster) way to achieve the same thing?
Solution
I haven't found any input which isn't handled well by your code. Here are some tests:
So, it works but it isn't an easy task to read it. If this isn't a bottleneck in an application I would use a
I think it's easier to read and maintain.
Finally, a note: according to Code Conventions for the Java Programming Language the name of your method should be
Methods should be verbs, in mixed case with the first letter
lowercase, with the first letter of each internal word capitalized.
Edit:
Apache Commons Math also uses long conversion:
As well as Guava:
assertTrue(CanAdd(0, Integer.MAX_VALUE));
assertTrue(CanAdd(0, Integer.MIN_VALUE));
assertTrue(CanAdd(Integer.MIN_VALUE, 0));
assertTrue(CanAdd(-1, Integer.MAX_VALUE));
assertFalse(CanAdd(1, Integer.MAX_VALUE));
assertFalse(CanAdd(-1, Integer.MIN_VALUE));So, it works but it isn't an easy task to read it. If this isn't a bottleneck in an application I would use a
long:public static boolean canAdd(int... values) {
long sum = 0;
for (final int value: values) {
sum += value;
if (sum > Integer.MAX_VALUE) {
return false;
}
if (sum < Integer.MIN_VALUE) {
return false;
}
}
return true;
}I think it's easier to read and maintain.
Finally, a note: according to Code Conventions for the Java Programming Language the name of your method should be
canAdd (with lowercase first letter).Methods should be verbs, in mixed case with the first letter
lowercase, with the first letter of each internal word capitalized.
Edit:
Apache Commons Math also uses long conversion:
public static int addAndCheck(int x, int y)
throws MathArithmeticException {
long s = (long)x + (long)y;
if (s Integer.MAX_VALUE) {
throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_ADDITION, x, y);
}
return (int)s;
}As well as Guava:
public static int checkedAdd(int a, int b) {
long result = (long) a + b;
checkNoOverflow(result == (int) result);
return (int) result;
}Code Snippets
assertTrue(CanAdd(0, Integer.MAX_VALUE));
assertTrue(CanAdd(0, Integer.MIN_VALUE));
assertTrue(CanAdd(Integer.MIN_VALUE, 0));
assertTrue(CanAdd(-1, Integer.MAX_VALUE));
assertFalse(CanAdd(1, Integer.MAX_VALUE));
assertFalse(CanAdd(-1, Integer.MIN_VALUE));public static boolean canAdd(int... values) {
long sum = 0;
for (final int value: values) {
sum += value;
if (sum > Integer.MAX_VALUE) {
return false;
}
if (sum < Integer.MIN_VALUE) {
return false;
}
}
return true;
}public static int addAndCheck(int x, int y)
throws MathArithmeticException {
long s = (long)x + (long)y;
if (s < Integer.MIN_VALUE || s > Integer.MAX_VALUE) {
throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_ADDITION, x, y);
}
return (int)s;
}public static int checkedAdd(int a, int b) {
long result = (long) a + b;
checkNoOverflow(result == (int) result);
return (int) result;
}Context
StackExchange Code Review Q#6255, answer score: 21
Revisions (0)
No revisions yet.