2010-03-09 3 views
2

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

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

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

Что я делаю неправильно?

+0

Ваше вычитание, даже если оно выполнено правильно, уменьшит значения char 0, 1, 2 ... 9 до двоичных чисел 0, 1, 2 ... 9. Любое значение ниже «0» фактически станет отрицательным, но char будет значением без знака. То, что вы пытаетесь сделать, недействительно и не имеет смысла. Используйте то, что предлагает cletus. См. Мой ответ, если вы действительно хотите это сделать. –

ответ

0

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

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

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

Это решило проблему, но теперь цифре не присвоено значение вообще ... – Troy

+0

@Troy: 'digit' должно быть присвоено значение, это примитивный тип. Является ли значение двоичным 0? Это имело бы смысл, если charAt (0) был «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 Promotion от Java Language Specification:

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

+1

@Troy, почему бы не использовать регулярное выражение say '\ d \ d- \ d \ d' и проверить вход пользователя для этого? Если нет, использование 'Character.isDigit()' может выполнить требуемую проверку. – cletus

+0

+1: Способ показать мне. –

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."); 

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

Смежные вопросы