2009-05-10 8 views
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.parseInt(minHex, 16)); 
    } 
} 

даетJava отрицательна INT проклясть и обратно не удается

-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) 

Что вверх?

ответ

10

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

+0

было бы здорово, если бы был способ для преобразования из шестнадцатеричной в Int/длинный только размещение битов не заботясь о знаке. Таким образом, можно было бы конвертировать туда и обратно с минимальными накладными расходами. – akostadinov

1

Необходимо, чтобы include a negative знак.

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

Integer min = Integer.MIN_VALUE + 1; 

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

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

2

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

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

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

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

Простейшим обходным путем является использование Long.parseLong() вместо этого, а затем преобразование результата в int.

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

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

0

Это похоже на работу для меня:

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)); 
} 
} 

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

3

Согласовывающий документация, 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)); 
    }