You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解析Java Integer.parseInt(String s, int radix)源码的溢出检测与负数处理疑问

Let's dive into these two key design decisions in Integer.parseInt—they're clever optimizations to handle integer overflow correctly and efficiently.

First, here's the source code we're looking at for reference:

public static int parseInt(String s, int radix) throws NumberFormatException {
    /*
     * WARNING: This method may be invoked early during VM initialization
     * before IntegerCache is initialized. Care must be taken to not use
     * the valueOf method.
     */
    if (s == null) {
        throw new NumberFormatException("s == null");
    }

    if (radix < Character.MIN_RADIX) {
        throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX");
    }

    if (radix > Character.MAX_RADIX) {
        throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX");
    }

    int result = 0;
    boolean negative = false;
    int i = 0, len = s.length();
    int limit = -Integer.MAX_VALUE;
    int multmin;
    int digit;

    if (len > 0) {
        char firstChar = s.charAt(0);
        if (firstChar < '0') { // Possible leading "+" or "-"
            if (firstChar == '-') {
                negative = true;
                limit = Integer.MIN_VALUE;
            } else if (firstChar != '+')
                throw NumberFormatException.forInputString(s);

            if (len == 1) // Cannot have lone "+" or "-"
                throw NumberFormatException.forInputString(s);
            i++;
        }
        multmin = limit / radix;
        while (i < len) {
            // Accumulating negatively avoids surprises near MAX_VALUE
            digit = Character.digit(s.charAt(i++), radix);
            if (digit < 0) {
                throw NumberFormatException.forInputString(s);
            }
            if (result < multmin) {
                throw NumberFormatException.forInputString(s);
            }
            result *= radix;
            if (result < limit + digit) {
                throw NumberFormatException.forInputString(s);
            }
            result -= digit;
        }
    } else {
        throw NumberFormatException.forInputString(s);
    }
    return negative ? result : -result;
}

Why keep result negative during calculation?

This is all about handling the asymmetric range of Java's int type. Remember:

  • Integer.MAX_VALUE is 2147483647 (2^31 - 1)
  • Integer.MIN_VALUE is -2147483648 (-2^31)

The negative side has one more possible value than the positive side. If we tried to accumulate the result as a positive number, we'd hit a problem when parsing the string -2147483648 (the smallest possible int). Its absolute value is 2147483648, which is larger than Integer.MAX_VALUE—so trying to store that as a positive int would cause an overflow before we could negate it.

By keeping result negative from the start:

  • We can directly accumulate the full range of possible values without overflowing. For -2147483648, we just end up with result = -2147483648, which fits perfectly.
  • For positive numbers, we just negate the final negative result to get the correct positive value (since -result will be within Integer.MAX_VALUE).

It's a neat trick to avoid having to handle two separate overflow cases for positive and negative numbers—we just use the larger negative range to cover all possibilities.

How does multmin detect overflow?

multmin is a precomputed threshold to catch overflow before it happens when we multiply result by the radix. Let's break it down:

  1. First, limit is set to -Integer.MAX_VALUE for positive numbers, or Integer.MIN_VALUE for negative numbers. This is the smallest (most negative) value our result can reach without overflowing.
  2. multmin = limit / radix—this is the threshold: if result is less than multmin, then multiplying result by radix would make it smaller than limit (i.e., overflow).

Take an example for positive numbers (where limit = -2147483647):

  • Suppose radix is 10, so multmin = -2147483647 / 10 = -214748364
  • If result is -214748365, which is less than multmin, then result * 10 = -2147483650—this is smaller than limit (-2147483647), which is an overflow. We throw an exception before doing the multiplication to avoid this.

After passing that check, we multiply result by radix, then check if result < limit + digit. This catches the case where subtracting the digit would push result below limit. The code does result -= digit, which rearranges to result = result - digit. We need this value to stay above or equal to limit, so rearranged that means result >= limit + digit. If result < limit + digit, then result - digit would be less than limit—another overflow scenario we need to block.

Together, multmin and the second check cover all possible overflow cases during the accumulation process.

内容的提问来源于stack exchange,提问作者tanvi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:48:38