1. 程式人生 > >java 字串轉化為整數溢位問題處理

java 字串轉化為整數溢位問題處理

1、思路及注意事項 概括起來有幾種情況 1)字串開頭是“+”號或“-”號的處理 2)非法字元的判斷(不是數字) 3)整數溢位問題。     看看Java函式庫中的Integer.parseInt(String sting)的原始碼如何處理這些問題的。
  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. publicstaticint parseInt(String string) throws NumberFormatException {  
  12.     return parseInt(string, 10);  
  13. }  
  14. /** 
  15.  * Parses the specified string as a signed integer value using the specified 
  16.  * radix. The ASCII character \u002d ('-') is recognized as the minus sign.
     
  17.  * 
  18.  * @param string 
  19.  *            the string representation of an integer value. 
  20.  * @param radix 
  21.  *            the radix to use when parsing. 
  22.  * @return the primitive integer value represented by {@code string} using 
  23.  *         {@code radix}. 
  24.  * @throws NumberFormatException 
  25.  *             if {@code string} cannot be parsed as an integer value,
     
  26.  *             or {@code radix < Character.MIN_RADIX || 
  27.  *             radix > Character.MAX_RADIX}. 
  28.  */
  29. publicstaticint parseInt(String string, int radix) throws NumberFormatException {  
  30.     if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {  
  31.         thrownew NumberFormatException("Invalid radix: " + radix);  
  32.     }  
  33.     if (string == null) {  
  34.         throw invalidInt(string);  
  35.     }  
  36.     int length = string.length(), i = 0;  
  37.     if (length == 0) {  
  38.         throw invalidInt(string);  
  39.     }  
  40.     boolean negative = string.charAt(i) == '-';  
  41.     if (negative && ++i == length) {  
  42.         throw invalidInt(string);  
  43.     }  
  44.     return parse(string, i, radix, negative);  
  45. }  
  46. privatestaticint parse(String string, int offset, int radix, boolean negative) throws NumberFormatException {  
  47.     int max = Integer.MIN_VALUE / radix;  
  48.     int result = 0, length = string.length();  
  49.     while (offset < length) {  
  50.         int digit = Character.digit(string.charAt(offset++), radix);  
  51.         if (digit == -1) {  
  52.             throw invalidInt(string);  
  53.         }  
  54.         if (max > result) {  
  55.             throw invalidInt(string);  
  56.         }  
  57.         int next = result * radix - digit;  
  58.         if (next > result) {  
  59.             throw invalidInt(string);  
  60.         }  
  61.         result = next;  
  62.     }  
  63.     if (!negative) {  
  64.         result = -result;  
  65.         if (result < 0) {  
  66.             throw invalidInt(string);  
  67.         }  
  68.     }  
  69.     return result;  
  70. }  
 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、參考原始碼實現字串轉化為整數
  1. publicclass StringToIntTest {  
  2.     /** 
  3.      * @author 曹豔豐  北京大學 
  4.      */
  5.     publicstaticvoid main(String[] args) {  
  6.         // TODO 自動生成的方法存根
  7.         try {  
  8.             System.out.println(parseInt("cao21'''474fefda8364fe7"));  
  9.             System.out.println(parseInt("-2147483648"));  
  10.             System.out.println(parseInt("-2147483651"));  
  11.             System.out.println(parseInt("-2147483648"));  
  12.             System.out.println(parseInt("-21474836410"));  
  13.         } catch (MyException e) {  
  14.             // TODO 自動生成的 catch 塊
  15.             e.printStackTrace();  
  16.         }  
  17.     }  
  18.     privatestaticint parseInt(String string) throws MyException {  
  19.         /* 異常情況1:字串為null */
  20.         if (string == null) {  
  21.             thrownew MyException("字串為null!");  
  22.         }  
  23.         int length = string.length(), offset = 0;  
  24.         /* 異常情況2:字串長度為0 */
  25.         if (length == 0) {  
  26.             thrownew MyException("字串長度為0!");  
  27.         }  
  28.         boolean negative = string.charAt(offset) == '-';  
  29.         /* 異常情況3:字串為'-' */
  30.         if (negative && ++offset == length) {  
  31.             thrownew MyException("字串為:'-'!");  
  32.         }  
  33.         int result = 0;  
  34.         char[] temp = string.toCharArray();  
  35.         while (offset < length) {  
  36.             char digit = temp[offset++];  
  37.             if (digit <= '9' && digit >= '0') {  
  38.                 int currentDigit = digit - '0';  
  39.                 /* 
  40.                  * 異常情況4:已經等於Integer.MAX_VALUE / 10,判斷要新增的最後一位的情況: 
  41.                  * 如果是負數的話,最後一位最大是8 如果是正數的話最後一位最大是7 
  42.                  */
  43.                 if (result == Integer.MAX_VALUE / 10) {  
  44.                     if ((negative == false && currentDigit > 7)  
  45.                             || (negative && currentDigit > 8)) {  
  46.                         thrownew MyException("溢位!");  
  47.                     }  
  48.                     /* 
  49.                      * 異常情況5:已經大於Integer.MAX_VALUE / 10