How can I detect integer overflow on 32 bits int?

45,119

Solution 1

Math.addExact throws exception on overflow

Since Java 8 there is a set of methods in the Math class:

…and versions for long as well.

Each of these methods throws ArithmeticException if overflow happens. Otherwise they return the proper result if it fits within the range.

Example of addition:

int x = 2_000_000_000;
int y = 1_000_000_000;
try {
    int result = Math.addExact(x, y);
    System.out.println("The proper result is " + result);
} catch(ArithmeticException e) {
    System.out.println("Sorry, " + e);
}

See this code run live at IdeOne.com.

Sorry, java.lang.ArithmeticException: integer overflow

Solution 2

long test = (long)x+y;
if (test > Integer.MAX_VALUE || test < Integer.MIN_VALUE)
   // Overflow!

Solution 3

Try this way:

boolean isOverflow(int left, int right) {
    return right > 0
            ? Integer.MAX_VALUE - right < left
            : Integer.MIN_VALUE - right > left;
}

From: https://wiki.sei.cmu.edu/confluence/display/java/NUM00-J.+Detect+or+prevent+integer+overflow

Solution 4

Overflow can be detected by a logical expression of the most significant bit of the two operands and the (truncated) result (I took the logical expression from the MC68030 manual):

/**
 * Add two int's with overflow detection (r = s + d)
 */
public static int add(int s, int d) throws ArithmeticException {
    int r = s + d;
    if (((s & d & ~r) | (~s & ~d & r)) < 0)
        throw new ArithmeticException("int overflow add(" + s + ", " + d + ")");
    return r;
}

Solution 5

The most intuitive method I can think of: calculate the sum (or difference) as a long, then convert that sum to an int and see if its value has changed.

long longSum = (long) a + b;
int sum = (int) longSum;
if (sum == longSum) {
    // sum contains the correct result
} else {
    // overflow/underflow
}

Remember that on modern 64 bit processors, working with longs is no less efficient than working with ints (the opposite may be true). So if you have a choice between checking for overflows or using longs, go for the latter.

Share:
45,119

Related videos on Youtube

ashur
Author by

ashur

Updated on October 23, 2020

Comments

  • ashur
    ashur over 3 years

    I know such topic was asked several times, but my question is about overflow on full 32 bits of int. For example:

      11111111111111111111111111111111 +
      00000000000000000000000000000001 =
      00000000000000000000000000000000   //overflow!
    

    I found topic with similar question about this, however the algorithm is not perfect.

      11111111111111111111111111111111 +
      00000000000000000000000000000000 =
      00000000000000000000000000000000  //overflow!
    

    Is there any simple, fast, safer way to check this ?

  • cellepo
    cellepo over 5 years
    Are x & y assumed to be long's themselves? If they were instead int's, I don't think this would work (since the overflow would go undetected before the long cast); am I correct?
  • Tim B
    Tim B over 5 years
    You are not correct. X gets cast to long before addition (precedence). long+int the int gets converted to long and you end up with long+long. Therefore the entire operation is done at 64 bit precision.
  • cellepo
    cellepo over 5 years
    Ah ok so the cast has precedence over the addition operator. Thanks!
  • expert
    expert over 5 years
    Overflow in isOverflow(-47483648, -100000000) is not detected.
  • ahmdx
    ahmdx over 5 years
    This is not an overflow actually :)
  • rveach
    rveach almost 5 years
    Java 8's addExact is coded as if (((s ^ r) & (d ^ r)) < 0).