Как использовать Integer без знака в Java 8 и Java 9?
В Oracle "Примитивные типы данных" страница он упоминает, что Java 8 добавляет поддержку беззнаковых ints и longs:
int
: По умолчанию тип данных int
представляет собой 32-разрядное двухзначное целочисленное целое число, которое имеет минимальное значение -2 31 и максимальное значение 2 31 -1. В Java SE 8 и более поздних версиях вы можете использовать тип данных int
для представления 32-разрядного целого числа без знака, которое имеет минимальное значение 0 и максимальное значение 2 32 - 1. Используйте класс Integer
для использования типа данных int
как целое число без знака. Дополнительную информацию см. В разделе "Классы номеров". Статические методы, такие как compareUnsigned
, divideUnsigned
и т.д., Были добавлены в класс Integer
для поддержки арифметических операций для целых чисел без знака.
long
: Тип данных long
- это 64-битное целое число из двух дополнений. Подписанное long
имеет минимальное значение -2 63 и максимальное значение 2 63 -1. В Java SE 8 и более поздних версиях вы можете использовать тип данных long
для представления беззнакового 64-битного long
, который имеет минимальное значение 0 и максимальное значение 2 64 -1. Используйте этот тип данных, если вам нужен диапазон значений, отличный от значений, предоставляемых int. Класс long
также содержит методы типа compareUnsigned
, divideUnsigned
и т.д. Для поддержки арифметических операций для unsigned long
.
Однако я не нашел способа объявить unsigned long или integer. Следующий код, например, дает сообщение об ошибке компилятора "литеральный вне диапазона" (я, конечно, использую Java 8), когда он должен находиться в диапазоне (назначенное значение равно 2 64 -1):
public class Foo {
static long values = 18446744073709551615L;
public static void main(String[] args){
System.out.println(values);
}
}
Итак, есть ли способ объявить unsigned int или long?
Ответы
Ответ 1
В документации, которую вы отправили, и это сообщение в блоге - нет никакой разницы при объявлении примитива между unsigned int/long и подписанным, "Новая поддержка" - это добавление статических методов в классах Integer и Long, например. Integer.divideUnsigned. Если вы не используете эти методы, ваш "unsigned" long выше 2 ^ 63-1 является просто старым длинным с отрицательным значением.
Из быстрого сглаживания не выглядит способ объявления целочисленных констант в диапазоне вне +/- 2 ^ 31-1 или +/- 2 ^ 63-1 для длин. Вам придется вручную вычислить отрицательное значение, соответствующее вашему положительному значению вне диапазона.
Ответ 2
Ну, даже в Java 8, long
и int
все еще подписаны, только некоторые методы рассматривают их так, как будто они были неподписанными. Если вы хотите написать беззнаковый long
литерал, подобный этому, вы можете сделать
static long values = Long.parseUnsignedLong("18446744073709551615");
public static void main(String[] args) {
System.out.println(values); // -1
System.out.println(Long.toUnsignedString(values)); // 18446744073709551615
}
Ответ 3
// Java 8
int vInt = Integer.parseUnsignedInt("4294967295");
System.out.println(vInt); // -1
String sInt = Integer.toUnsignedString(vInt);
System.out.println(sInt); // 4294967295
long vLong = Long.parseUnsignedLong("18446744073709551615");
System.out.println(vLong); // -1
String sLong = Long.toUnsignedString(vLong);
System.out.println(sLong); // 18446744073709551615
// Guava 18.0
int vIntGu = UnsignedInts.parseUnsignedInt(UnsignedInteger.MAX_VALUE.toString());
System.out.println(vIntGu); // -1
String sIntGu = UnsignedInts.toString(vIntGu);
System.out.println(sIntGu); // 4294967295
long vLongGu = UnsignedLongs.parseUnsignedLong("18446744073709551615");
System.out.println(vLongGu); // -1
String sLongGu = UnsignedLongs.toString(vLongGu);
System.out.println(sLongGu); // 18446744073709551615
/**
Integer - Max range
Signed: From −2,147,483,648 to 2,147,483,647, from −(2^31) to 2^31 – 1
Unsigned: From 0 to 4,294,967,295 which equals 2^32 − 1
Long - Max range
Signed: From −9,223,372,036,854,775,808 to 9,223,372,036,854,775,807, from −(2^63) to 2^63 − 1
Unsigned: From 0 to 18,446,744,073,709,551,615 which equals 2^64 – 1
*/
Ответ 4
Нет способа, как объявлять unsigned long или int в Java 8 или Java 9. Но некоторые методы рассматривают их так, как будто они были неподписанными, например:
static long values = Long.parseUnsignedLong("123456789012345678");
но это не declaration переменной.
Ответ 5
Если использование сторонней библиотеки является опцией, есть jOOU (отключение библиотеки из jOOQ), который предлагает типы обертки для целых чисел без знака в Java. Это не совсем то же самое, что поддержка примитивного типа (и, следовательно, байтового кода) для неподписанных типов, но, возможно, это все еще достаточно хорошо для вашего прецедента.
import static org.joou.Unsigned.*;
// and then...
UByte b = ubyte(1);
UShort s = ushort(1);
UInteger i = uint(1);
ULong l = ulong(1);
Все эти типы расширяются java.lang.Number
и могут быть преобразованы в примитивные типы более высокого порядка и BigInteger
.
(Отказ от ответственности: я работаю в компании за этими библиотеками)