Java addExact 方法在分配给变量时未检测到整数溢出

Java addExact method does not detect Integer Overflow when assigned to a variable

我有以下 try 块来检测整数溢出。

    try {

        Math.addExact((number % 10) * (int) Math.pow(10, i), reversedNumber);

    } catch(ArithmeticException ae) {

        return 0;

    }

好的,所以如果我 运行 上面的代码按原样进行,它会按预期导致 ArithmeticException。但是,如果我想将 addExact 的结果赋值给一个整型变量,则永远不会检测到溢出。

    try {

        reversedNumber = Math.addExact((number % 10) * (int) Math.pow(10, i), reversedNumber);

    } catch(ArithmeticException ae) {

        return 0;

    }

谁能告诉我为什么在赋值给变量时没有捕获异常?是因为赋值过程本身就成功了,所以没有抛出异常吗?

public static int reverse(int x) {

    int number = Math.abs(x);
    if(number == 0) return number;

    int numberOfDigits = (int) Math.log10(number) + 1;
    
    int reversedNumber = 0;
    for(int i = numberOfDigits - 1; i >= 0; i--) {

        try {

            reversedNumber = Math.addExact((number % 10) * (int) Math.pow(10, i), reversedNumber);

        } catch(ArithmeticException ae) {

            return 0;

        }


        number /= 10;

    }

    return x < 0 ? -reversedNumber : reversedNumber;

}

输入 1534236469,答案应为 0。

这与你是否将它分配给一个变量无关。你的方法正确returns 0 对于输入 1534236469 错误的原因,如果你不把它分配给 reversedNumber。对于 1534236469,addExact 不会以任何方式抛出异常。

加法并没有溢出,这也是addExact不抛出异常的原因。但是(number % 10) * (int) Math.pow(10, i)的乘法是溢出。在循环的第一次迭代中,您乘以 9 * 1000000,这超出了 int.

的范围

addExact 只检查你传递给它的两个参数相加的溢出。它不会在计算两个参数本身时检查溢出。

您需要使用multiplyExact:

int powerOf10 = (int) Math.pow(10, i);
int digit = (number % 10);
reversedNumber = Math.addExact(Math.multiplyExact(digit, powerOf10), reversedNumber);]