Integer.parseInt(string) 实际上是如何工作的?

2022-09-01 09:14:51

最近被问到这个问题,不知道答案。从高层次上可以解释Java如何获取字符/字符串并将其转换为int。


答案 1

通常这是这样完成的:

  • 初始化结果为 0
  • 对于字符串中的每个字符,请执行此操作
    • 结果 = 结果 * 10
    • 从字符中获取数字(“0”是48 ASCII(或0x30),因此只需从字符ASCII代码中减去该数字即可获得数字)
    • 将数字添加到结果中
  • 返回结果

编辑:如果您将10替换为正确的基数并调整从相应字符获得的数字,则适用于任何基数(对于低于10的基数应按原样工作,但对于较高的基数(如十六进制),则需要稍作调整,因为字母与数字之间由7个字符分隔)。

编辑2:字符到数字值的转换:字符“0”到“9”的ASCII值为48到57(0x30以六进制0x39),因此为了将字符转换为其数字值,需要简单的减法。通常它是这样完成的(其中 ord 是提供字符的 ASCII 代码的函数):

digit = ord(char) - ord('0')

对于较高的数字基数,字母用作“数字”(六进制中的A-F),但字母从65(0x41六进制)开始,这意味着我们必须考虑一个间隙:

digit = ord(char) - ord('0')
if digit > 9 then digit -= 7

示例:'B' 是 66,所以 ord('B') - ord('0') = 18。由于18大于9,我们减去7,最终结果将是11 - “数字”B的值。

这里还有一点需要注意 - 这仅适用于大写字母,因此必须首先将数字转换为大写字母。


答案 2

Java API的源代码是免费提供的。下面是 parseInt() 方法。它相当长,因为它必须处理许多特殊和角落的情况。

public static int parseInt(String s, int radix) throws NumberFormatException {
    if (s == null) {
        throw new NumberFormatException("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, max = s.length();
    int limit;
    int multmin;
    int digit;

    if (max > 0) {
        if (s.charAt(0) == '-') {
            negative = true;
            limit = Integer.MIN_VALUE;
            i++;
        } else {
            limit = -Integer.MAX_VALUE;
        }
        multmin = limit / radix;
        if (i < max) {
            digit = Character.digit(s.charAt(i++), radix);
            if (digit < 0) {
                throw NumberFormatException.forInputString(s);
            } else {
                result = -digit;
            }
        }
        while (i < max) {
            // 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);
    }
    if (negative) {
        if (i > 1) {
            return result;
        } else { /* Only got "-" */
            throw NumberFormatException.forInputString(s);
        }
    } else {
        return -result;
    }
}