Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Wiki Markup
Failure to account for integer overflow has resulted in failures of real systems, for instance, when implementing the {{compareTo()}} method. The meaning of the return value of the {{compareTo()}} method is defined only in terms of its sign and whether it is zero; the magnitude of the return value is irrelevant. Consequently, an apparent --- but incorrect --- optimization would be to subtract the operands and return the result. For operands of opposite sign, this can result in integer overflow; thusconsequently violating the {{compareTo()}} contract \[[Bloch 2008, item 12|AA. Bibliography#Bloch 08]\].

...

For all integral types other than long, the next larger integral type can represent the result of any one single integral operationsoperation. For example, operations on values of type int, can be performed using type long. ThusTherefore, we can perform an operation using the larger type and range-check before downcasting to the original type. Note, however, that this guarantee holds only for a single one arithmetic operation; larger expressions without per-operation bounds checks may overflow the larger type.

Because type long is the largest primitive integral type, the only alternative possible way to use a larger type and downcast is to perform arithmetic operations using the BigInteger class, range-check as above , and then convert the result back to type long.

This compliant solution converts two variables of type int to type long, performs the addition of the long values, and range checks the result before converting back to type int using a range-checking method. The range-checking method determines whether its input can be represented by type int. If so, it returns the downcast result; otherwise it throws an ArithmeticException.

Code Block
bgColor#ccccff

public int do_operation(int a, int b) throws ArithmeticException {
  return intRangeCheck((long) a + (long) b);
}

// Either perform a safe downcast to int, or throw ArithmeticException
public static int intRangeCheck(long val) throws ArithmeticException {
   if (val > Integer.MAX_VALUE || val < Integer.MIN_VALUE) {
     throw new ArithmeticException("Out of range");
   }
   return (int)val; // Value within range; downcast is safe
}

...