...
Code Block | ||
---|---|---|
| ||
static final int safeAdd(int left, int right) throws ArithmeticException { if (right > 0 ? left > Integer.MAX_VALUE - right : left < Integer.MIN_VALUE - right) { throw new ArithmeticException("Integer overflow"); } return left + right; } static final int safeSubtract(int left, int right) throws ArithmeticException { if (right > 0 ? left < Integer.MIN_VALUE + right : left > Integer.MAX_VALUE + right) { throw new ArithmeticException("Integer overflow"); } return left - right; } static final int safeMultiply(int left, int right) throws ArithmeticException { if (right > 0 ? left > Integer.MAX_VALUE/right || left < Integer.MIN_VALUE/right : (right < -1 ? left > Integer.MIN_VALUE/right || left < Integer.MAX_VALUE/right : right == -1 && left == Integer.MIN_VALUE) ) { throw new ArithmeticException("Integer overflow"); } return left * right; } static final int safeDivide(int left, int right) throws ArithmeticException { if ((left == Integer.MIN_VALUE) && (right == -1)) { throw new ArithmeticException("Integer overflow"); } return left / right; } static final int safeNegate(int a) throws ArithmeticException { if (a == Integer.MIN_VALUE) { throw new ArithmeticException("Integer overflow"); } return -a; } static final int safeAbs(int a) throws ArithmeticException { if (a == Integer.MIN_VALUE) { throw new ArithmeticException("Integer overflow"); } return Math.abs(a); } |
...
Code Block | ||
---|---|---|
| ||
public static int multAccum(int oldAcc, int newVal, int scale) throws ArithmeticException { return safeAdd(oldAcc, safeMultiply(newVal, scale)); } |
...
Code Block | ||
---|---|---|
| ||
public static int multAccum(int oldAcc, int newVal, int scale) { return Math.addExact(oldAcc, throws ArithmeticException { return Math.addExact(oldAcc, Math.multiplyExact(newVal, Math.multiplyExact(newVal, scale)); } |
Compliant Solution (Upcasting)
...
Code Block | ||
---|---|---|
| ||
public static long intRangeCheck(long value) throws ArithmeticException { if ((value < Integer.MIN_VALUE) || (value > Integer.MAX_VALUE)) { throw new ArithmeticException("Integer overflow"); } return value; } public static int multAccum(int oldAcc, int newVal, int scale) throws ArithmeticException scale) { final long res = intRangeCheck( ((long) oldAcc) + intRangeCheck((long) newVal * (long) scale) ); return (int) res; // Safe downcast } |
...
Code Block | ||
---|---|---|
| ||
private static final BigInteger bigMaxInt = BigInteger.valueOf(Integer.MAX_VALUE); private static final BigInteger bigMinInt = BigInteger.valueOf(Integer.MIN_VALUE); public static BigInteger intRangeCheck(BigInteger val) throws ArithmeticException { if (val.compareTo(bigMaxInt) == 1 || val.compareTo(bigMinInt) == -1) { throw new ArithmeticException("Integer overflow"); } return val; } public static int multAccum(int oldAcc, int newVal, int scale) throws ArithmeticException { BigInteger product = BigInteger.valueOf(newVal).multiply(BigInteger.valueOf(scale)); BigInteger res = intRangeCheck(BigInteger.valueOf(oldAcc).add(product)); return res.intValue(); // Safe conversion } |
...