Java中的数字溢出

thi*_*man 0 java integer-overflow atoi

我特林实现C/C++中的atoi功能的Java,以下是代码片段

    for (int j = 0; j < s.length(); j++) {

        int digit = Character.digit(s.charAt(j), 10);
        if (sum < limit/10) {
            if (neg) return Integer.MIN_VALUE;
            return Integer.MAX_VALUE;
        }

        sum *= 10;
        if (sum < limit + digit) {
            if (neg) return Integer.MIN_VALUE;
            return Integer.MAX_VALUE;
        }
        sum -= digit;
    }
Run Code Online (Sandbox Code Playgroud)

对于行"if (sum < limit + digit) {",这是正确的,但是,如果我使用"sum - digit < limit",它将得到错误的结果,例如输入"-2147483649",错误的结果2147483647,应该是-2147483648.

我想出来了,因为总和 - 数字可能会溢出,所以这又出现了另一个问题:

    int sum = Integer.MAX_VALUE;
    System.out.println(sum < Integer.MAX_VALUE + 1);
Run Code Online (Sandbox Code Playgroud)

为什么这个打印错误?什么是逻辑背后?

har*_*old 6

Integer.MAX_VALUE + 1等于Integer.MIN_VALUE,如果你用十六进制看它们会更明显:

Integer.MAX_VALUE = 0x7fffffff
                1 = 0x00000001
                    ---------- +
                    0x80000000
Run Code Online (Sandbox Code Playgroud)

而且0x80000000也被称为Integer.MIN_VALUE.

显然没有int低于Integer.MIN_VALUE.

此外,试图通过查看数字是否大于最大可能值来测试数字是否已经溢出从根本上是错误的.它不能大于最大可能值,这就是"最大可能"所暗示的.此外,您不能取一个数字,查看它,并确定它是否已溢出,因为每个数字都可能是非溢出计算的结果(实际上只是将其写为常量)和溢出的计算结果.你需要知道你是如何得到这个数字的.