2014-09-24 83 views
1

我編寫了Java代碼將String轉換爲long。但是,在處理溢出問題時,我沒有線索如何解決它。如果一個數字溢出,計算機相信每個數字在存儲中都是合法的。 如何讓程序用64bit jdk檢測實數溢出是關鍵問題。而且我不允許使用任何內置庫,如parseLong或其他。將字符串轉換爲Long,沒有內置庫

public static long strTolong(String s){ 
     //error checking 
     if(s == null) return 0; 
     s = s.trim();//remove all space character 
     boolean neg = false;//judge the number is negative or positive 
     int pos = 0 ; //index of string 
     long result = 0; 
     //check positive or negative 
     if(s.charAt(pos) == '-'){ 
      neg = true; 
      pos++; 
     }else if(s.charAt(pos) == '+') pos++; 

     //calculate result 
     while(pos<s.length()){ 
      if(s.charAt(pos) >='0' && s.charAt(pos) <='9'){ 
       result = result*10+(s.charAt(pos) - '0'); 
      }else 
       break; 
      pos++; 
     } 
     if(neg) result =-result; 

     //check overflow 
     if(result >Long.MAX_VALUE) { 
      return Long.MAX_VALUE; 
     } 
     if(result<Long.MIN_VALUE){ 
      return Long.MIN_VALUE; 
     } 


     return result; 
    } 

如果數據大於long.maxvalue,結果不能被正確地存儲在計算機中。

如何解決這個問題?

+3

「Long.parseLong(」102「);'?是什麼問題? – 2014-09-24 07:49:54

回答

1

你最好的選擇可能是做輸入和最小值之間的逐一比較/最大數,然後再開始。

if (compare(s, ""+Long.MIN_VALUE) == -1) 
    throw new NumberFormatException("Input too small"); 

if (compare(s, ""+Long.MAX_VALUE) == 1) 
    throw new NumberFormatException("Input too large"); 

這裏測試:http://ideone.com/HmMkJ3

注意,代碼不檢查輸入以及形成

static int compare(String v1, String v2) { 
    boolean neg1 = v1.startsWith("-"); 
    boolean neg2 = v2.startsWith("-"); 
    return neg1 ? (neg2 ? -comparePositives(v1.substring(1),v2.substring(1)):-1) 
       : (neg2 ? 1 : comparePositives(v1, v2)); 
} 

static int comparePositives(String v1, String v2) { 
    // Is one longer? 
    if (v1.length() != v2.length()) 
     return v1.length() < v2.length() ? -1 : 1; 

    // Both empty? 
    if (v1.isEmpty()) 
     return 0; 

    // First digit differs? 
    if (v1.charAt(0) != v2.charAt(0)) 
     return v1.charAt(0) < v2.charAt(0) ? -1 : 1; 

    // Recurse on rest of number 
    return comparePositives(v1.substring(1), v2.substring(1)); 
} 

如下使用它的實例。我建議你先做這樣的檢查。 (請注意類似0-0等的情況)

+0

您的解決方案令人印象深刻。但是,此處使用內置庫。正則表達式的方式也是如此。 – 2014-09-24 20:37:18

+0

關鍵問題是電腦不會注意到數據溢出。 – 2014-09-24 20:38:26

+0

答覆已更新。 – aioobe 2014-09-25 18:25:58

0

你可以做同樣的事情,長期#parseLong會做:

throw new NumberFormatException("too long (pun intended): "+s); 
+0

問題是電腦不會注意到數據溢出。 – 2014-09-24 20:34:02

0

我不確定你想在這裏實現什麼。如果String大於Long.MAX_VALUE意味着不再是Long的值。

如果您的String值在Long的範圍內,那麼您可以使用Long.parseLong()這種困難的方式。

如果你想擁有大量可以使用BigDecimal容易

String max = Long.MAX_VALUE+""; 
System.out.println(max); 
long maxL=Long.parseLong(max)+1; 
System.out.println(maxL); 
BigDecimal bigDecimal=new BigDecimal(max).add(new BigDecimal("1")); 
System.out.println(bigDecimal); 

輸出地說:如果值小於大於Long.MAX_VALUE

9223372036854775807 // long max value 
-9223372036854775808 // incorrect result in long 
9223372036854775808 // BigDecimal gives you correct one 

對於你的情況,你可以拋出一個異常Long.MIN_VALUE

+0

看看它說「//檢查溢出」的代碼。 – aioobe 2014-09-24 08:04:10

+0

@aioobe你想說什麼? – 2014-09-24 08:09:16

+0

*「如果String大於Long.MAX_VALUE表示不再是Long值」* - 我確定OP知道這一點。他面臨的問題是他無法通過執行'result> Long.MAX_VALUE'來檢查溢出,因爲'result'很長。 – aioobe 2014-09-24 08:17:49