Java отрицательный int для шестнадцатеричного и обратного сбоев
public class Main3 { public static void main(String[] args) { Integer min = Integer.MIN_VALUE; String minHex = Integer.toHexString(Integer.MIN_VALUE); System.out.println(min + " " + minHex); System.out.println(Integer.parseInt(minHex, 16)); } }
дает
-2147483648 80000000 Exception in thread "main" java.lang.NumberFormatException: For input string: "80000000" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48) at java.lang.Integer.parseInt(Integer.java:459) at Main3.main(Main3.java:7)
Что происходит?
- Обосновать последнюю строку div?
- Сортировка текстового файла по длине строки, включая пробелы
- Тайм-аут в async / wait
- Как добавить разрыв строки в Android TextView?
- Как читать и анализировать CSV-файлы на C ++?
- Хороший цвет текста переднего плана для заданного цвета фона
- Усечение длинных строк с помощью CSS: возможно?
- Как настроить кнопку UISwitch в iphone?
- Ограниченный выбор в JTextField / JTextComponent?
- Можно ли написать вертикально в текстовом виде в android?
- Эффективность анализа (если, TryParse, Try-Catch)
- Как я могу определить кодировку / кодовую страницу текстового файла
- Вертикальная (повернутая) метка в Android
Задокументировано, что Integer.toHexString
возвращает строковое представление целого в качестве значения без знака – в то время как Integer.parseInt
принимает подписанный int. Если вы используете Integer.toString(value, 16)
вы получите то, что хотите.
Это то, что меня всегда раздражало. Если вы инициализируете int шестнадцатеричным литералом, вы можете использовать весь диапазон положительных значений до 0xFFFFFF
; что-то большее, чем 0x7FFFFF
, действительно будет отрицательным. Это очень удобно для маскировки бит и других операций, в которых вы заботитесь только о местах бит, а не о их значениях.
Но если вы используете Integer.parseInt () для преобразования строки в целое число, все, что больше, чем "0x7FFFFFFF"
, рассматривается как ошибка. Вероятно, есть веская причина, почему они так поступают, но это все еще расстраивает.
Простейшим обходным решением является использование Long.parseLong () вместо этого, а затем вывод результата в int.
int n = (int)Long.parseLong(s, 16);
Конечно, вы должны сделать это, только если вы уверены, что число будет в диапазоне Integer.MIN_VALUE..Integer.MAX_VALUE
.
Согласно документации, toHexString
возвращает «строковое представление целочисленного аргумента как целое число без знака в базе 16».
Таким образом, правильная обратная операция, вероятно, Integer.parseUnsignedInt
которая была введена как часть Java 8:
public class Main3 { public static void main(String[] args) { Integer min = Integer.MIN_VALUE; String minHex = Integer.toHexString(Integer.MIN_VALUE); System.out.println(min + " " + minHex); System.out.println(Integer.parseUnsignedInt(minHex, 16)); }
Попробуй это:
public class Main3 { public static void main(String[] args) { Integer min = Integer.MIN_VALUE; String minHex = Integer.toHexString(Integer.MIN_VALUE); System.out.println(min + " " + minHex); System.out.println(Integer.parseInt( "-" + minHex, 16)); }
}
для этого:
-2147483648 80000000 -2147483648
Вам нужно включить отрицательный знак.
У меня нет доступа, чтобы проверить это прямо сейчас, но я бы поставил, если вы попробовали это значение вместо этого:
Integer min = Integer.MIN_VALUE + 1;
Он не бомбил, но дал бы вам положительное число (не отрицательное), когда вы запустили ParseInt(min,16)
.
Строка битов на самом деле не имеет достаточной информации для определения знака в этом контексте, поэтому вам необходимо его предоставить. (рассмотрите случай, когда вы используете min = "F"
. Это +/- F? Если вы преобразовали его в биты и увидели 1111, и вы знали, что это байт, вы можете сделать вывод, что это отрицательно, но это много сослагательное наклонение.
Кажется, это работает для меня:
public class Main3 { public static void main(String[] args) { Integer min = Integer.MIN_VALUE; String minHex = Integer.toHexString(Integer.MIN_VALUE); System.out.println(min + " " + minHex); System.out.println((int)Long.parseLong(minHex, 16)); } }
Целое число анализируется как «подписанный длинный», который обрабатывает такое большое положительное число, а затем знак возвращается обратно, отбрасывая его на «int».