Автор оригинала: mkyong.
Просмотрите следующий пример Java, чтобы преобразовать отрицательное целое число в двоичной строке обратно в целочисленный тип.
String binary = Integer.toBinaryString(-1); // convert -1 to binary // 11111111 11111111 11111111 11111111 (two's complement) int number = Integer.parseInt(binary, 2); // convert negative binary back to integer System.out.println(number); // output ??
Результатом является Исключение NumberFormatException
!
Exception in thread "main" java.lang.NumberFormatException: For input string: "11111111111111111111111111111111" under radix 2 at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:68) at java.base/java.lang.Integer.parseInt(Integer.java:652) at com.mkyong.crypto.bytes.Byte2.main(Byte2.java:17)
Исключение NumberFormatException
вызвано переполнением строки 11111111111111111111111111111111
(длина 32) не могут вписаться в 32-битный int
тип?
Примечание Целое число имеет значения от -2^31
до 2^31-1
, а не 2^32-1
.
1. Переполнение целых чисел?
В Java int
представляет собой 32-битное дополнение к двум целое число, первый крайний левый бит или самый значимый бит обозначает знак чисел, 0 является положительным, 1 отрицательным.
{1}1111111 11111111 11111111 11111111 = {1} = most significant bit, denote positive or negative
Поскольку крайний левый бит зарезервирован для знака чисел, Java int
32 бита содержит только значения из -2^31 (-2,147,483,648)
чтобы 2^31-1 (2,147,483,647)
.
System.out.println(Integer.MIN_VALUE); // -2,147,483,648 , -2^31 System.out.println(Integer.MAX_VALUE); // 2,147,483,647 , 2^31-1
Просмотрите двоичную строку еще раз, то есть полные 32 бита, 2^32-1 (4,294,967,295)
. Тип int
не может обрабатывать такое большое число, и Java не поддерживает unsigned int
.
11111111 11111111 11111111 11111111
2. Длинный
Чтобы решить ее, мы можем использовать long
, 64-битное целое число, дополняющее два, имеет значения из -2^63
до 2^63-1
.
String binary = Integer.toBinaryString(-1); //int number = Integer.parseInt(binary, 2); long l = Long.parseLong(binary, 2); // 11111111 11111111 11111111 11111111 int number = (int) l; System.out.println(number); // -1
3. Java 8
Для Java 8 он представил новые API для поддержки неподписанных
операций, попробуйте Integer.parseunsignedint()
.
String binary = Integer.toBinaryString(-1); //int number = Integer.parseInt(binary, 2); int number = Integer.parseUnsignedInt(binary, 2); System.out.println(number); // -1
Рекомендации
- Примитивные типы данных Java
- Расширение знака Java
- Википедия – дополнение для двоих
Оригинал: “https://mkyong.com/java/java-convert-negative-binary-to-integer/”