java 字符串转化为整数溢出问题处理

1、思路及注意事项
参考: http://blog.sina.com.cn/s/blog_514c89a90100d7qh.html
概括起来有几种情况
1)字符串开头是“+”号或“-”号的处理
2)非法字符的判断(不是数字)
3)整数溢出问题。
    看看Java函数库中的Integer.parseInt(String sting)的源码如何处理这些问题的。
[java]  view plain copy
  1. /** 
  2.  * Parses the specified string as a signed decimal integer value. The ASCII 
  3.  * character \u002d ('-') is recognized as the minus sign. 
  4.  * 
  5.  * @param string 
  6.  *            the string representation of an integer value. 
  7.  * @return the primitive integer value represented by {@code string}. 
  8.  * @throws NumberFormatException 
  9.  *             if {@code string} cannot be parsed as an integer value. 
  10.  */  
  11. public static int parseInt(String string) throws NumberFormatException {  
  12.     return parseInt(string, 10);  
  13. }  
  14.    
  15. /** 
  16.  * Parses the specified string as a signed integer value using the specified 
  17.  * radix. The ASCII character \u002d ('-') is recognized as the minus sign. 
  18.  * 
  19.  * @param string 
  20.  *            the string representation of an integer value. 
  21.  * @param radix 
  22.  *            the radix to use when parsing. 
  23.  * @return the primitive integer value represented by {@code string} using 
  24.  *         {@code radix}. 
  25.  * @throws NumberFormatException 
  26.  *             if {@code string} cannot be parsed as an integer value, 
  27.  *             or {@code radix < Character.MIN_RADIX || 
  28.  *             radix > Character.MAX_RADIX}. 
  29.  */  
  30. public static int parseInt(String string, int radix) throws NumberFormatException {  
  31.     if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {  
  32.         throw new NumberFormatException("Invalid radix: " + radix);  
  33.     }  
  34.     if (string == null) {  
  35.         throw invalidInt(string);  
  36.     }  
  37.     int length = string.length(), i = 0;  
  38.     if (length == 0) {  
  39.         throw invalidInt(string);  
  40.     }  
  41.     boolean negative = string.charAt(i) == '-';  
  42.     if (negative && ++i == length) {  
  43.         throw invalidInt(string);  
  44.     }  
  45.    
  46.     return parse(string, i, radix, negative);  
  47. }  
  48.    
  49. private static int parse(String string, int offset, int radix, boolean negative) throws NumberFormatException {  
  50.     int max = Integer.MIN_VALUE / radix;  
  51.     int result = 0, length = string.length();  
  52.     while (offset < length) {  
  53.         int digit = Character.digit(string.charAt(offset++), radix);  
  54.         if (digit == -1) {  
  55.             throw invalidInt(string);  
  56.         }  
  57.         if (max > result) {  
  58.             throw invalidInt(string);  
  59.         }  
  60.         int next = result * radix - digit;  
  61.         if (next > result) {  
  62.             throw invalidInt(string);  
  63.         }  
  64.         result = next;  
  65.     }  
  66.     if (!negative) {  
  67.         result = -result;  
  68.         if (result < 0) {  
  69.             throw invalidInt(string);  
  70.         }  
  71.     }  
  72.     return result;  
  73. }  
 parseInt(String string, int radix)判断了
1)radix进制超出范围 Character. MIN_RADIX  = 2, Character. MAX_RADIX )=36)
2)字符串为null
3)字符串长度为空
4)字符串第一位为“-”且只有一位
  没有异常之后进行parse(String string, int offset, int radix, boolean negative)判断,参数即字符串,偏移量,进制,negative(如果开头没有“-”则offset=0,negative=false,否则为offset=1,neagtive=true)
   在parse(String string, int offset, int radix, boolean negative)主要进行了溢出的判断。利用offset++来控制移动, 在while (offset < length) 循环中直到倒数第二位的时候,如果已经小于 max = Integer.MIN_VALUE / radix的话表明一定会溢出。例如"-2147483648"
倒数第二位的时候 :result=-214748364,max=-214748364,max>result不成立表明可以进行最后一位的处理。
     这里为什么不先求得当前的结果再同Integer.MIN_VALUE比较?而是先同Integer.MIN_VALUE / radix比较再决定是否进行下一位的添加?不言而喻。
2、参考源码实 现字符串转化为整数
  可以对比http://zhedahht.blog.163.com/blog/static/25411174200731139971/。
[java]  view plain copy
  1. public class StringToIntTest {  
  2.    
  3.     /** 
  4.      * @author 曹艳丰  北京大学 
  5.      */  
  6.     public static void main(String[] args) {  
  7.         // TODO 自动生成的方法存根  
  8.         try {  
  9.             System.out.println(parseInt("cao21'''474fefda8364fe7"));  
  10.             System.out.println(parseInt("-2147483648"));  
  11.             System.out.println(parseInt("-2147483651"));  
  12.             System.out.println(parseInt("-2147483648"));  
  13.             System.out.println(parseInt("-21474836410"));  
  14.         } catch (MyException e) {  
  15.             // TODO 自动生成的 catch 块  
  16.             e.printStackTrace();  
  17.         }  
  18.    
  19.     }  
  20.    
  21.     private static int parseInt(String string) throws MyException {  
  22.         /* 异常情况1:字符串为null */  
  23.         if (string == null) {  
  24.             throw new MyException("字符串为null!");  
  25.         }  
  26.         int length = string.length(), offset = 0;  
  27.         /* 异常情况2:字符串长度为0 */  
  28.         if (length == 0) {  
  29.             throw new MyException("字符串长度为0!");  
  30.         }  
  31.         boolean negative = string.charAt(offset) == '-';  
  32.         /* 异常情况3:字符串为'-' */  
  33.         if (negative && ++offset == length) {  
  34.             throw new MyException("字符串为:'-'!");  
  35.         }  
  36.         int result = 0;  
  37.         char[] temp = string.toCharArray();  
  38.         while (offset < length) {  
  39.             char digit = temp[offset++];  
  40.             if (digit <= '9' && digit >= '0') {  
  41.                 int currentDigit = digit - '0';  
  42.                 /* 
  43.                  * 异常情况4:已经等于Integer.MAX_VALUE / 10,判断要添加的最后一位的情况: 
  44.                  * 如果是负数的话,最后一位最大是8 如果是正数的话最后一位最大是7 
  45.                  */  
  46.                 if (result == Integer.MAX_VALUE / 10) {  
  47.    
  48.                     if ((negative == false && currentDigit > 7)  
  49.                             || (negative && currentDigit > 8)) {  
  50.                         throw new MyException("溢出!");  
  51.                     }  
  52.                     /* 
  53.                      * 异常情况5:已经大于Integer.MAX_VALUE / 10 
  54.                      * 无论最后一位是什么都会超过Integer.MAX_VALUE 
  55.                      */  
  56.                 } else if (result > Integer.MAX_VALUE / 10) {  
  57.                     throw new MyException("溢出!");  
  58.                 }  
  59.    
  60.                 int next = result * 10 + currentDigit;  
  61.                 result = next;  
  62.             }  
  63.         }  
  64.         if (negative) {  
  65.             result = -result;  
  66.         }  
  67.         return result;  
  68.     }  
  69.    
  70. }  
  71.    
  72. /* 自定义异常 */  
  73. class MyException extends Exception {  
  74.     /** 
  75.      * 
  76.      */  
  77.     private static final long serialVersionUID = 1749149488419303367L;  
  78.     String message;  
  79.    
  80.     public MyException(String message) {  
  81.         // TODO 自动生成的构造函数存根  
  82.         this.message = message;  
  83.     }  
  84.    
  85.     @Override  
  86.     public String getMessage() {  
  87.         // TODO 自动生成的方法存根  
  88.         return message;  
  89.     }  
  90.    
  91. }  
****************************

“如果是负数的话,最后一位最大是8 如果是正数的话最后一位最大是7”可以用Integer.MIN_VALUE%10和Integer.MAX_VALUE%10来求。

转自:http://blog.csdn.net/brillianteagle/article/details/39029351?utm_source=tuicool

你可能感兴趣的:(Java)