Как использовать целое число без знака в Java 8 и Java 9?
в Oracle "примитивные типы данных" страница, в нем упоминается, что Java 8 добавляет поддержку неподписанных ints и longs:
int
по умолчаниюint
тип данных представляет собой 32-битное целое число, имеющее минимальное значение -231 и максимальное значение 231-1. в Java SE 8 и более поздних, вы можете использоватьint
тип данных для представления 32-разрядного целого числа без знака, имеющего минимальное значение 0 и максимальное значение 232-1. использоватьInteger
классint
тип данных как целое число без знака. Дополнительную информацию см. В разделе классы чисел. Статические методы, такие какcompareUnsigned
,divideUnsigned
etc были добавлены кInteger
класс для поддержки арифметических операций для целых чисел без знака.
long
: Thelong
тип данных-это 64-разрядное целое число дополнения two. Подписанныйlong
минимальное значение -263 и a максимальное значение 263-1. в Java SE 8 и более поздних, вы можете использоватьlong
тип данных для представления 64-разрядной версии без знакаlong
, который имеет минимальное значение 0 и максимальное значение 264-1. используйте этот тип данных, когда вам нужен диапазон значений шире, чем те, которые предоставляются int. ЭлементLong
класс также содержит методы, такие какcompareUnsigned
,divideUnsigned
etc для поддержки арифметических операций для unsignedlong
.
однако, я не нахожу способ объявления длинного или целого числа без знака. Следующий код, например, дает сообщение об ошибке компилятора "литерал находится вне диапазона" (я использую Java 8, Конечно), когда он должен быть в диапазоне (назначенное значение точно 264-1):
public class Foo {
static long values = 18446744073709551615L;
public static void main(String[] args){
System.out.println(values);
}
}
Итак, есть ли способ объявить unsigned int или long?
5 ответов:
в документации, которую вы разместили, и этот блог - нет никакой разницы при объявлении примитива между беззнаковым int / long и подписанным. "Новая поддержка" - это добавление статических методов в целочисленные и длинные классы, например целое число.divideUnsigned. Если вы не используете эти методы, ваш "unsigned" long above 2^63-1-это просто старый длинный с отрицательным значением.
от быстрого скима, это не похоже, что есть способ объявления констант в диапазоне за пределами +/- 2^31-1, или +/- 2^63-1 для лонгов. Вам придется вручную вычислить отрицательное значение, соответствующее вашему положительному значению вне диапазона.
Ну, даже в 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 }
// 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 */
нет никакого способа, как объявить an unsigned long или int в Java 8 и Java 9. Но некоторые методы рассматривают их как неподписанные, например:
static long values = Long.parseUnsignedLong("123456789012345678");
но это не декларация переменной.
Если вы используете стороннюю библиотеку, есть 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
.(отказ от ответственности: я работаю на компанию, стоящую за этими библиотеками)