2010-03-09 70 views
2

我從用戶那裏得到一個字符串,然後進行一些檢查以確保它是有效的,這裏是我一直使用的代碼;可能會損失精度;從字符串中提取字符

char digit= userInput.charAt(0) - '0'; 

這一直工作正常,直到我做了另一種方法的一些工作,我去編譯,並已接收從那時起一個錯誤「可能的精度損失」。

我在做什麼錯?

+0

您的減法,即使它正確轉換,也會將char值0,1,2 ... 9減少爲二進制0,1,2 ... 9。任何低於'0'的值都將變爲負值,但char是無符號值。你試圖做的是無效的,沒有意義。使用cletus的建議。看到我的答案,如果你真的想這樣做。 – 2010-03-09 05:01:25

回答

0

在執行減法操作之前,Java可能會將userInput.charAt(0)'0'轉換爲其他數據類型,然後再轉換回來。

儘量明確鑄造結果char將其存儲到數字之前:

char digit = (char)(userInput.charAt(0) - '0'); 
+0

這解決了這個問題,但現在數字根本沒有賦值... – Troy 2010-03-09 03:16:19

+0

@Troy:'數字'必須被賦值,它是一個原始類型。值是二進制0嗎?如果charAt(0)是'0',這將是有意義的。 – 2010-03-09 04:58:20

6

一件事,你應該使用Character方法實現此目的,而不是一個家庭長大的解決方案,即Character.isDigit()檢查的有效性和Character.digit()爲得到一個值:

char c = ... 
if (Character.isDigit(c)) { 
    // it's a digit 
} 
int value = Character.digit(c, 10); 

爲什麼你得到這個警告是5.6.2 Binary Numeric Promotion從解釋3210:

當操作者施加二進制 數值提升到一對 操作數,其中的每一個必須表示一個數字型的 值,以下 規則適用,爲了使用加寬 轉換(§5.1.2)至 操作數轉換爲必要的:

  • 如果操作數是double型的,另一種是轉換爲 double
  • 否則,如果任一操作數的類型爲float,則另一個操作數轉換爲 爲float
  • 否則,如果任一操作數的類型爲long,則另一個轉換爲 long
  • 否則,兩個操作數都轉換爲int類型。

那麼,有什麼情況是,當你做減法兩個參數被晉升爲int秒。結果是int。當您嘗試將int分配給char時,可能會丟失精度(32位有符號16位無符號)。

另一種驗證方法是簡單地使用正則表達式:

if (s.matches("\\d\\d-\\d\\d")) { 
    // it's ##-## 
} 

,或者,如果你需要獲取組:

Pattern p = Pattern.compile("(\\d\\d)-(\\d\\d)"); 
Matcher m = p.matcher(s); 
if (m.matches()) { 
    System.out.println(m.group(1)); // first group 
    System.out.println(m.group(1)); // second group 
} 
+0

問題是我正在檢查以確保用戶輸入格式爲digitdigit-digitdigit的字符串,如果它不匹配,或者數字超出了範圍,我正在檢查然後我想返回一個錯誤。 – Troy 2010-03-09 03:19:57

+1

@Troy爲什麼不使用'\ d \ d- \ d \ d'的正則表達式並測試用戶輸入?如果沒有,使用'Character.isDigit()'可以做你想要的驗證。 – cletus 2010-03-09 03:28:28

+0

+1:給我看的方式。 – 2010-03-09 05:56:41

0

這與做如何的Java隱含蒙上操作數與算術運算符一起使用時。

兩個userInput.charAt(0)'0'char類型,但是它們被隱式轉換爲整數的操作(減法),因此當整數結果被分配給一個char,Java將給出錯誤。

0

你真的應該使用cletus的答案,我給他+1。但是,如果您真的想在代碼中使用該減法,則不應將結果存儲在char之內,因爲結果可能爲負值(例如,如果用戶輸入「」(空格))。

int digit = userInput.charAt(0) - '0'; 
if (digit < 0 || digit > 9) 
    throw new IllegalArgumentException("Bad input at 0, must be between 0 and 9."); 

當然,這不應該有一個硬編碼的索引或者,除非你真的只是想 檢查字符串的第一個位置。