Как разобрать любую допустимую строку на целое число, используя определенную систему счисления?

Фон

Используя Integer.parseInt(someIntString , основание счисления) не всегда работает и в некоторых случаях может возвращать исключение NumberFormatException.

Я проверил API, и он говорит, что будет возвращено такое исключение:

если строка не может быть проанализирована как целочисленное значение или система счисления ‹ Character.MIN_RADIX || основание > Символ.MAX_RADIX.

Пример кода, который вызывает исключение:

System.out.println(Integer.parseInt("ff00ff00",16));

В java я получаю такое же исключение.

Поскольку целое число содержит 4 байта, это все еще должно работать, но это не так.

Вот доказательство того, что такое возможно:

final String input="ff00ff00";
int output=0;
for(int i=0;i<input.length();++i)
  {
  output<<=4;
  final char c=input.charAt(i);
  if(c>='a')
    output+=c-'a'+10;
  else output+=c-'0';
  }
System.out.println(output);
System.out.println(Integer.toHexString(output));

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

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

Вопрос

Есть ли встроенная функция или известный алгоритм для преобразования строки в целое число с использованием любой системы счисления?

Я предполагаю, конечно, что целочисленная переменная может содержать значение (используя максимум 4 байта) и что знак числа не имеет значения.


person android developer    schedule 17.04.2013    source источник
comment
@yoah Обновил вопрос, так как он неверен с его предположениями. Извиняюсь.   -  person android developer    schedule 17.04.2013
comment
ff00ff00 также не анализирует Java. 00ff00ff делает, я думаю, что это связано с разбором Java значения со знаком, поэтому вы можете использовать -123a. Насколько я вижу, Android делает то же самое.   -  person yoah    schedule 17.04.2013
comment
@йоа, я вижу. Есть ли решение, предполагающее, что это всегда будет использоваться для положительных значений?   -  person android developer    schedule 17.04.2013


Ответы (2)


Хорошо, я думаю, что для этого вопроса нет встроенного решения, но его довольно легко решить, используя примерно тот же код, который я написал в вопросе:

public static int parseInt(final String input,final int radix)
  {
  int output=0;
  for(int i=0;i<input.length();++i)
    {
    output*=radix;
    final char c=input.charAt(i);
    if(c>='a')
      output+=c-'a'+10;
    else output+=c-'0';
    }
  return output;
  }
person android developer    schedule 17.04.2013

Проблема в том, что java не поддерживает целые числа без знака, поскольку "ff00ff00" больше, чем может быть положительный int, java считает его вне допустимого диапазона. Простое решение состоит в том, чтобы использовать Long.parseLong(string, radix), в идеале вы должны изменить тип затронутых переменных на longs, но вы также можете заставить его работать с некоторым хитрым приведением.

person joshbooks    schedule 08.04.2014
comment
независимо от того. решение, которое я написал, вероятно, достаточно хорошо. использование типа переменной большего диапазона не всегда возможно (что бы вы сделали после долгого использования? использовать BigInteger?) . кроме того, вы должны знать, когда использовать другой тип, и для этого вам нужно выполнить дополнительные вычисления, чтобы узнать, подходит ли он к диапазону или нет. - person android developer; 08.04.2014