Возможная потеря точности; извлечение символа из строки - PullRequest
2 голосов
/ 09 марта 2010

Я получаю строку от пользователя, а затем провожу некоторую проверку, чтобы убедиться, что она действительна, вот код, который я использовал;

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

Это работало нормально, пока я не поработал над другим методом, я пошел на компиляцию и с тех пор получаю сообщение об ошибке "возможной потери точности".

Что я делаю не так?

Ответы [ 4 ]

6 голосов
/ 09 марта 2010

Во-первых, вы должны использовать Character методы для этого, а не решение для дома, а именно Character.isDigit() для проверки действительности и Character.digit() для получения значения:

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

Почему вы получаете это предупреждение, объясняется 5.6.2 Двоичное числовое продвижение из Спецификации языка Java :

Когда оператор применяет двоичный числовое продвижение на пару операнды, каждый из которых должен обозначать значение числового типа, следующее правила применяются по порядку, используя расширение преобразование ( §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 голосов
/ 09 марта 2010

Вы действительно должны использовать ответ Клетуса, и я дал ему +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.");

Конечно, это не должно иметь жестко закодированный индекс, если только вы действительно не хотите проверьте первую позицию этой строки.

0 голосов
/ 09 марта 2010

Это связано с тем, как Java неявно преобразует операнды при использовании с арифметическими операторами.

Оба userInput.charAt(0) и '0' имеют тип char, но они неявно преобразуются в целые числа для операции (вычитания), и, следовательно, когда целочисленный результат присваивается char, Java выдаст ошибку.

0 голосов
/ 09 марта 2010

Java может преобразовывать userInput.charAt(0) и '0' в другой тип данных перед выполнением вычитания, а затем преобразовывать обратно.

Попробуйте явно привести результат к char перед сохранением его в цифру:

char digit = (char)(userInput.charAt(0) - '0');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...