简体   繁体   中英

Possible loss of precision; extracting char from string

I am getting a string from the user and then doing some checking to make sure it is valid, here is the code I have been using;

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

This had been working fine until I did some work on another method, I went to compile and have been receiving a 'possible loss of precision' error since then.

What am I doing wrong?

For one thing you should be using the Character methods for doing this rather than a home grown solution, namely Character.isDigit() for checking validity and Character.digit() for getting a value:

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

Why you're getting this warning is explained by 5.6.2 Binary Numeric Promotion from the Java Language Specification :

When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value of a numeric type, the following rules apply, in order, using widening conversion ( §5.1.2 ) to convert operands as necessary:

  • If either operand is of type double , the other is converted to double .
  • Otherwise, if either operand is of type float , the other is converted to float .
  • Otherwise, if either operand is of type long , the other is converted to long .
  • Otherwise, both operands are converted to type int .

So what's happening is that when you do the subtraction both arguments are being promoted to int s. The result is an int . When you try and assign that int to a char there is a possible loss of precision (32 bit signed to 16 bit unsigned).

An alternative validation technique is simply to use a regular expression:

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

or, if you need to grab the groups:

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
}

Java may be converting userInput.charAt(0) and '0' to a different datatype before doing the subtraction, then converting back afterwards.

Try explicitly casting the result to char before storing it into digit:

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

This has to do with how Java implicitly casts operands when used with arithmetic operators.

Both userInput.charAt(0) and '0' are of type char but they are implicitly converted to integers for the operation (subtraction) and hence when the integer result is assigned to a char , Java will given an error.

You really should use cletus' answer and I gave him +1. However, if you really want to use that subtraction in your code you should not store the result in a char at all, since the result can be negative (if the user enters " " (space) for instance).

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

Of course, this should not have a hard coded index either unless you really just want to check the first position of that string.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM