了解Java Integer.parseInt(字符串s,int基数)源代码

了解Java Integer.parseInt(字符串s,int基数)源代码,java,integer,integer-overflow,Java,Integer,Integer Overflow,我在看java.lang.Integer的parseInt方法的源代码 public static int parseInt(String s, int radix) throws NumberFormatException { /* * WARNING: This method may be invoked early during VM initialization * before IntegerCache is initialized.

我在看java.lang.Integer的parseInt方法的源代码

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;
}
公共静态int-parseInt(字符串s,int基数)
抛出NumberFormatException
{
/*
*警告:此方法可能在VM初始化的早期调用
*在初始化IntegerCache之前。必须注意不要使用
*方法的价值。
*/
如果(s==null){
抛出新的NumberFormatException(“s==null”);
}
if(基数<字符最小基数){
抛出新的NumberFormatException(“基数”+基数+
“小于字符。最小基数”);
}
if(基数>字符最大基数){
抛出新的NumberFormatException(“基数”+基数+
“大于字符的最大基数”);
}
int结果=0;
布尔负=假;
int i=0,len=s.length();
int limit=-Integer.MAX_值;
int multmin;
整数位数;
如果(len>0){
char firstChar=s.charAt(0);
if(firstChar<'0'){//可能的前导“+”或“-”
if(firstChar=='-'){
负=真;
限制=整数.MIN_值;
}else if(firstChar!='+'))
抛出NumberFormatException.forInputString;
if(len==1)//不能有单独的“+”或“-”
抛出NumberFormatException.forInputString;
i++;
}
multmin=极限/基数;
而(我
我可以看到,
multmin
不知何故被用来检测正负两侧的整数溢出。但我很难理解怎么做

我也不明白为什么我们在计算时将结果保留为负数,如果没有检测到负数,则在最后将其设置为正数。

multmin
是如何工作的?
multmin
用于以下代码:

if (result < multmin) {
    throw NumberFormatException.forInputString(s);
}
if(结果
  • 如果当前结果小于
    multmin
    ,则下一代结果 必须溢出,因此引发异常:

    如果结果结果<极限/基数(beacause multmin=极限/基数)
    ------>结果*基数<极限
    ------>结果*基数-数字<限制(溢出)。

  • 如果当前结果大于或等于
    multmin
    ,我们可以 断言
    结果*基数>=限制
    不溢出,因此继续检查
    结果*基数-数字
    是否溢出:

    if(结果<限值+位数){
    抛出NumberFormatException.forInputString;
    }

为什么要用负片? 因为
Integer.MIN\u值(-2147483648)
绝对值大于
Integer.MAX\u值(2147483647)

假设我们有一个正版本,当输入数字以“+”开头时,我们可以将
限制设置为
整数.MAX_值。

但是,当输入数字以“-”开头时,我们不能将
限制设置为
2147483648
,它是一个溢出值。

如果
s
表示超出
[integer.MIN_值,integer.MAX_值]
范围的整数,则此方法设计为引发异常,即
[-2147483648,2147483647]
范围

该算法执行重复的乘法和加法,最终可能导致溢出。该算法通过提前检查操作数来避免溢出

检查溢出 检查
result+digit
是否会导致溢出而不实际添加它们的最简单方法是检查:

if (result > limit - digit) // result, limit and digit are positive
if (result > limit / radix) // result, limit and radix are positive
检查
result*radix
是否会导致溢出而不实际乘以它们的最简单方法是检查:

if (result > limit - digit) // result, limit and digit are positive
if (result > limit / radix) // result, limit and radix are positive
这就解释了
limit=Integer.MAX..
multmin=limit/radix
的作用

为什么“消极积累”? 该算法将符号分离出来,并对剩余的数字进行运算(一种情况更容易处理)。它必须处理的一个特殊情况是
-2147483648
;在这种情况下,必须将限制设置为
2147483648
,这超出了
Integer
的范围

负累积时,可将限制设置为
-2147483648
。注意,上述“如果”条件必须针对负数进行调整,如下所示:

if (result < limit + digit) // result and limit are negative
if (result < limit / radix) // result and limit are negative