How to handle addition and subtraction beyond Integers MAX_VALUE and MIN_VALUE?

717 Views Asked by At

The following is the piece of code I am trying to implement:

if (n1 > 0 && n2 > 0 && result >= Integer.MAX_VALUE) {
    result = Integer.MAX_VALUE;
}
else if (n1 > 0 && n2 > 0 && (result <= Integer.MIN_VALUE || result < 0)) {
    result = Integer.MAX_VALUE;
}
else if (n1 < 0 && n2 < 0 && (result <= Integer.MIN_VALUE || result == 0)) {
    result = Integer.MIN_VALUE;
}

but I am not getting satisfactory results. For example, -2147483640-10 gives me 2147483646.

I am sure there has to be a more concrete way of doing saturation.

2

There are 2 best solutions below

0
On

It can be done as simply as:

return Math.min(Math.max((long) n1 + n2, Integer.MIN_VALUE), Integer.MAX_VALUE);

The operation (long) n1 + n2 ensures that the result is a long so that n1 + n2 neither overflows nor underflows.

The Math.max((long) n1 + n2, Integer.MIN_VALUE) ensure that in the case n1 + n2 would have underflow we get the value Integer.MIN_VALUE. Otherwise, we get the result of n1 + n2.

Finally, Math.min(.., Integer.MAX_VALUE) ensures that if n1 + n2 would have overflows the method returns Integer.MAX_VALUE. Otherwise, the operation n1 + n2 will be returned instead.

Running example:

public class UnderOver {

    public static long add(int n1, int n2){
       return Math.min(Math.max((long) n1 + n2, Integer.MIN_VALUE), Integer.MAX_VALUE);
    }

    public static void main(String[] args) {
        System.out.println(add(Integer.MAX_VALUE, 10));
        System.out.println(add(Integer.MIN_VALUE, -10));
        System.out.println(add(-10, -10));
        System.out.println(add(10, 10));
        System.out.println(add(10, 0));
        System.out.println(add(-20, 10));
    }
}

OUTPUT:

2147483647
-2147483648
-20
20
10
-10
0
On

If you need to set limits to Integer.MAX_VALUE and Integer.MIN_VALUE in case of overflow, you should track if sign of the result has changed to define when the overflow has taken place.

Unless result is long, there's no need to check conditions like result >= Integer.MAX_VALUE in case of positive overflow or result <= Integer.MAX_VALUE for negative overflow.

public static int add(int n1, int n2) {
    System.out.printf("%d + %d = ", n1, n2);
    int result = n1 + n2;

    if (n1 > 0 && n2 > 0 && result < 0) {
        result = Integer.MAX_VALUE;
    } else if (n1 < 0 && n2 < 0 && result > 0) {
        result = Integer.MIN_VALUE;
    }

    return result;
}

Tests:

System.out.println(add(10, 20));
System.out.println(add(2147483640, 10));

System.out.println(add(-10, -20));
System.out.println(add(-2147483640, -10));

Output:

10 + 20 = 30
2147483640 + 10 = 2147483647
-10 + -20 = -30
-2147483640 + -10 = -2147483648