На странице Oracle «Примитивные типы данных» упоминается, что в Java 8 добавлена поддержка беззнаковых целых и длинных чисел:
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
т.д. , чтобы поддерживать арифметические операции для беззнаковогоlong
.
Однако я не могу объявить беззнаковое длинное или целое число. Следующий код, например, выдает сообщение об ошибке компилятора «литерал вне допустимого диапазона» (я, конечно, использую 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?
Ответы:
Согласно опубликованной вами документации и этому сообщению в блоге - нет никакой разницы при объявлении примитива между неподписанным int / long и подписанным. «Новая поддержка» - это добавление статических методов в классы Integer и Long, например Integer.divideUnsigned. . Если вы не используете эти методы, ваша длинная длина «без знака» выше 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 */
источник
Там нет никакого способа , как объявить беззнаковое длинное или 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
.(Отказ от ответственности: я работаю в компании, стоящей за этими библиотеками)
источник