可能损失精度;从字符串中提取char

时间:2010-03-09 03:00:38

标签: java type-conversion

我从用户那里得到一个字符串然后做一些检查以确保它是有效的,这是我一直在使用的代码;

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

这个工作正常,直到我对另一个方法做了一些工作,我去编译并且从那时起一直收到'可能的精度损失'错误。

我做错了什么?

4 个答案:

答案 0 :(得分: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 PromotionJava Language Specification解释了为什么您收到此警告:

  

当运算符应用二进制时   数字促销到一对   操作数,每个都必须表示一个   数值类型的值,如下   规则适用于使用拓宽的顺序   要转换的转化(§5.1.2)   必要时操作数:

     
      
  • 如果任一操作数的类型为double,则另一个操作数将转换为   double
  •   
  • 否则,如果任一操作数的类型为float,则转换另一个操作数   到float
  •   
  • 否则,如果任一操作数的类型为long,则另一个操作数将转换为   long
  •   
  • 否则,两个操作数都将转换为int类型。
  •   

所以正在发生的事情是当你进行减法时,两个参数都被提升为int s。结果是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
}

答案 1 :(得分:0)

Java可能会在执行减法之前将userInput.charAt(0)'0'转换为其他数据类型,然后再转换回来。

尝试将结果显式转换为char,然后将其存储到数字中:

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

答案 2 :(得分:0)

这与Java在与算术运算符一起使用时隐式转换操作数有关。

userInput.charAt(0)'0'都是char类型,但是它们被隐式转换为操作(减法)的整数,因此当整数结果分配给{{1}时,Java会出错。

答案 3 :(得分:0)

你真的应该使用cletus的答案,我给了他+1。但是,如果您真的想在代码中使用该减法,则不应将结果存储在char中,因为结果可能是负数(例如,如果用户输入“”(空格))。 / p>

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

当然,除非你真的想要,否则它不应该有硬编码索引 检查该字符串的第一个位置。