Java отрицательный int в hex и обратно не удается - PullRequest
8 голосов
/ 10 мая 2009
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)

Как дела?

Ответы [ 6 ]

12 голосов
/ 10 мая 2009

Это то, что меня всегда раздражало. Если вы инициализируете int шестнадцатеричным литералом, вы можете использовать полный диапазон положительных значений до 0xFFFFFF; все, что больше 0x7FFFFF, будет действительно отрицательным значением. Это очень удобно для маскировки битов и других операций, когда вас интересуют только местоположения битов, а не их значения.

Но если вы используете Integer.parseInt () для преобразования строки в целое число, все, что больше "0x7FFFFFFF", будет считаться ошибкой. Вероятно, есть веская причина, почему они сделали это таким образом, но это по-прежнему расстраивает.

Самый простой обходной путь - использовать Long.parseLong (), а затем привести результат к int.

int n = (int)Long.parseLong(s, 16);

Конечно, вам следует делать это только в том случае, если вы уверены, что число будет в диапазоне Integer.MIN_VALUE..Integer.MAX_VALUE.

11 голосов
/ 10 мая 2009

Документально подтверждено, что Integer.toHexString возвращает строковое представление целого числа в виде значения без знака - в то время как Integer.parseInt принимает знаковое целое. Если вместо этого вы используете Integer.toString(value, 16), вы получите то, что хотите.

6 голосов
/ 06 декабря 2014

Согласно документации, 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));
    }
2 голосов
/ 10 мая 2009

Попробуйте это:

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
1 голос
/ 10 мая 2009

Вам необходимо включить отрицательный знак .

У меня нет доступа, чтобы проверить это прямо сейчас, но я бы поспорил, если вы попробуете это значение вместо:

Integer min = Integer.MIN_VALUE + 1;

Он не будет бомбить, но даст вам положительное число (не отрицательное), когда вы наберете ParseInt(min,16).

A строка битов на самом деле не достаточно информации для определения знака в этом контексте, поэтому вам нужно предоставить его. (рассмотрим случай, когда вы используете min = "F". Это +/- F? Если вы преобразовали его в биты и увидели 1111, и , вы знали, что это был байт, вы можете заключить, что он отрицательный, но это много если.

0 голосов
/ 27 ноября 2014

Мне кажется, это работает:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...