How does Java handle integer underflows and overflows and how would you check for it?

前端 未结 12 1361
走了就别回头了
走了就别回头了 2020-11-21 06:40

How does Java handle integer underflows and overflows?

Leading on from that, how would you check/test that this is occurring?

12条回答
  •  我在风中等你
    2020-11-21 07:12

    If it overflows, it goes back to the minimum value and continues from there. If it underflows, it goes back to the maximum value and continues from there.

    You can check that beforehand as follows:

    public static boolean willAdditionOverflow(int left, int right) {
        if (right < 0 && right != Integer.MIN_VALUE) {
            return willSubtractionOverflow(left, -right);
        } else {
            return (~(left ^ right) & (left ^ (left + right))) < 0;
        }
    }
    
    public static boolean willSubtractionOverflow(int left, int right) {
        if (right < 0) {
            return willAdditionOverflow(left, -right);
        } else {
            return ((left ^ right) & (left ^ (left - right))) < 0;
        }
    }
    

    (you can substitute int by long to perform the same checks for long)

    If you think that this may occur more than often, then consider using a datatype or object which can store larger values, e.g. long or maybe java.math.BigInteger. The last one doesn't overflow, practically, the available JVM memory is the limit.


    If you happen to be on Java8 already, then you can make use of the new Math#addExact() and Math#subtractExact() methods which will throw an ArithmeticException on overflow.

    public static boolean willAdditionOverflow(int left, int right) {
        try {
            Math.addExact(left, right);
            return false;
        } catch (ArithmeticException e) {
            return true;
        }
    }
    
    public static boolean willSubtractionOverflow(int left, int right) {
        try {
            Math.subtractExact(left, right);
            return false;
        } catch (ArithmeticException e) {
            return true;
        }
    }
    

    The source code can be found here and here respectively.

    Of course, you could also just use them right away instead of hiding them in a boolean utility method.

提交回复
热议问题