Во-первых, результаты вывода "раскомментированных" принтов будут разные для 16-ричных чисел от 0xA
до 0xF
.
Во-вторых, входная строка hexNumber
должна быть "нормализована", то есть в ней должны содержаться либо только прописные либо только строчные буквы, иначе HEX.indexOf
вернёт -1.
private static final String HEX = "0123456789ABCDEF";
public static int toDecimal(String hexNumber) {
int decimalNumber = 0;
for (int i = 0; i < hexNumber.length(); i++) {
decimalNumber = 16 * decimalNumber + HEX.indexOf(hexNumber.charAt(i)); //строка-1
// decimalNumber = 16 * decimalNumber + hexNumber.charAt(i); строка-2
System.out.println("hexNumber.charAt(i) = " + hexNumber.charAt(i));
System.out.println("HEX.indexOf(hexNumber.charAt(i)) = " + HEX.indexOf(hexNumber.charAt(i)));
}
return decimalNumber;
}
// тест
System.out.println(toDecimal("1AFc"));
Вывод:
hexNumber.charAt(i) = 1
HEX.indexOf(hexNumber.charAt(i)) = 1 // типа ок, '1' -> 1
hexNumber.charAt(i) = A
HEX.indexOf(hexNumber.charAt(i)) = 10 // не совпадает, символ 'A' (65 = 0x41) != 10
hexNumber.charAt(i) = F
HEX.indexOf(hexNumber.charAt(i)) = 15 // не совпадает, символ 'F' (70 = 0x46) != 15
hexNumber.charAt(i) = c
HEX.indexOf(hexNumber.charAt(i)) = -1 // символ 'c' не найден! -1
6895
Результат неверный, 0x1AFc == 6908
.
Обращение к HEX.indexOf
можно заменить обращением к методу Character::getNumericValue
, который возвращает корректные цифровые значения для символов, включая шестнадцатиричные.
public static int toDecimalFix(String hexNumber) {
int decimalNumber = 0;
for (char c : hexNumber.toCharArray()) {
decimalNumber = (decimalNumber << 4) + Character.getNumericValue(c);
}
return decimalNumber;
}
Для проверки можно использовать стандартные методы Integer::parseInt(String str, int radix)
, Integer::parseUnsignedInt(String str, int radix)
, Integer::valueOf(String str, int radix)
, в которые можно передать основание системы счисления.