zoukankan      html  css  js  c++  java
  • Java的字符串转int算法

    面T家,被要求实现一个字符串转整型数的算法,当时手写有点遗漏,现在回头来看看jdk的实现。
    常用的是Integer.valueOf方法来实现转换:

    1     public static Integer valueOf(String s) throws NumberFormatException {
    2         return Integer.valueOf(parseInt(s, 10));
    3     }

    默认会调用parseInt方法进行转换,参数中的10说明是按照10进制进行转换的。

    看看parseInt方法:

     1     public static int parseInt(String s, int radix)
     2                 throws NumberFormatException
     3     {
     4 
     5         if (s == null) {
     6             throw new NumberFormatException("null");
     7         }
     8 
     9         if (radix < Character.MIN_RADIX) {
    10             throw new NumberFormatException("radix " + radix +
    11                                             " less than Character.MIN_RADIX");
    12         }
    13 
    14         if (radix > Character.MAX_RADIX) {
    15             throw new NumberFormatException("radix " + radix +
    16                                             " greater than Character.MAX_RADIX");
    17         }
    18 
    19         int result = 0;
    20         boolean negative = false;
    21         int i = 0, len = s.length();
    22         int limit = -Integer.MAX_VALUE;
    23         int multmin;
    24         int digit;
    25 
    26         if (len > 0) {
    27             char firstChar = s.charAt(0);
    28             if (firstChar < '0') { // Possible leading "+" or "-"
    29                 if (firstChar == '-') {
    30                     negative = true;
    31                     limit = Integer.MIN_VALUE;
    32                 } else if (firstChar != '+')
    33                     throw NumberFormatException.forInputString(s);
    34 
    35                 if (len == 1) // Cannot have lone "+" or "-"
    36                     throw NumberFormatException.forInputString(s);
    37                 i++;
    38             }
    39             multmin = limit / radix;
    40             while (i < len) {
    41                 // Accumulating negatively avoids surprises near MAX_VALUE
    42                 digit = Character.digit(s.charAt(i++),radix);
    43                 if (digit < 0) {
    44                     throw NumberFormatException.forInputString(s);
    45                 }
    46                 if (result < multmin) {
    47                     throw NumberFormatException.forInputString(s);
    48                 }
    49                 result *= radix;
    50                 if (result < limit + digit) {
    51                     throw NumberFormatException.forInputString(s);
    52                 }
    53                 result -= digit;
    54             }
    55         } else {
    56             throw NumberFormatException.forInputString(s);
    57         }
    58         return negative ? result : -result;
    59     }

    首先看到5-17行是边界检查:

    • 如果字符串s是空指针,直接抛异常
    • 如果进制小于最小进制(常量定义为2),抛异常
    • 如果进制大于最大进制(常量定义为36),抛异常

    接下来19-24行是局部变量定义,这里需要注意一个就是limit被赋值为int表示的最大正整型数的负值,也就是-2147483647

    再往下看到26-38行,如果字符串s长度大于0,那么首先看看首字符

    • 如果首字符小于字符0,那么可能是符号 + 或者 - ,要区别对待了
      • 如果是符号 - ,说明是个负数,将布尔值变量negative设置为true,并将limit设置为int型整数的下限值,也就是-2147483648
      • 如果首字符不是符号 +,说明首字符既不是数字也不是符号,则抛出异常
    • 再接下来看,如果首字符是符号 - 或者 +,但是字符串长度只有1,也就是说只有一个符号,那么也是不能够转为整型数的,直接抛异常

    再往下39-54行

    局部变量mulmin赋值为limit除以当前转换的进制。接下来是一个循环,i代表处理的字符串的位数。
    用局部变量digit记录字符串s第i位数字的相应进制的值,接下来又是一些判断了:

    • 如果digit小于0,抛异常
    • 如果result变量小于mulmin,抛异常,这里可以限制之后的乘法操作肯定不溢出;之后result变量乘以当前转换进制。(如果result小于mulmin也就是limit/radix了,那么后面的乘以radix肯定就会小于limit,对于负数就超过了Integer的范围,对于正数也是超过了Integer.MAX_VALUE
    • 如果此时result小于limit加上digit,抛异常,这里可以限制之后的减法操作不会溢出;之后result变量减去digit的值。(这个抛异常和上一条原因类似,也是为了防止溢出)

    最后58行,如果negative为true,则直接返回result,否则返回负的result。

    这个有点意思,如果是负数直接输出,如果是正数反而是用负数取负,负负得正来表示的
    个人觉得应该是整型数从绝对值来看,负数的范围比正数大1,如果用result += digit这样来进行计算的话,那么最小值-2147483648会无法被正确转换。因为2147483640+8会得到-2147483648,然后再取负数的话,就变成0了。但是使用-=来计算,因为负数的范围更大,因此正数是可以全部表示出来的,而且不管是+0还是-0都不会有问题,都可以得到数值0

  • 相关阅读:
    DOS系统功能调用与BIOS中断调用 [转自KingofCoders]
    纯手工保护光盘数据(转)
    程序员不错的建议【转】
    初识逆向技术(转)
    Notepad++插件推荐JSMin
    jQuery Ready 与 Window onload 的区别
    Javascript typeof和instanceof判断数据类型
    浅谈Javascript 中几种克隆(clone)方式
    Javascript Array sort排序问题
    不同浏览器对display为none元素的图片处理不一样
  • 原文地址:https://www.cnblogs.com/noodleprince/p/9713336.html
Copyright © 2011-2022 走看看