Как использовать целое число без знака в 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
: элементlong
тип данных-64-разрядное целое число дополнения two. Подписанныйlong
минимальное значение -263 и a максимальное значение 263-1. в Java SE 8 и более поздних, вы можете использоватьlong
тип данных для представления беззнаковое 64-битноеlong
, который имеет минимальное значение 0 и максимальное значение 264-1. используйте этот тип данных, когда вам нужен диапазон значений шире, чем те, которые предоставлены int. TheLong
класс также содержит методы, такие какcompareUnsigned
,divideUnsigned
etc для поддержки арифметических операций для unsignedlong
.
однако, я не нахожу способ объявления unsigned long или integer. Следующий код, например, дает сообщение об ошибке компилятора "литерал вне диапазона" (я использую 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 ответов
в документации вы выложили, и этот блог - нет никакой разницы при объявлении примитива между unsigned int / long и подписанным. "Новая поддержка" - это добавление статических методов в целочисленные и длинные классы, например целое число.divideUnsigned. Если вы не используете эти методы, ваш "неподписанный" длинный выше 2^63-1-это просто старый длинный с отрицательным значением.
от быстрого обезжиренного, не похоже, что есть способ объявления целочисленных констант в диапазоне вне + / - 2^31-1 или + / - 2^63-1 для лонгов. Вам придется вручную вычислить отрицательное значение, соответствующее положительному значению вне диапазона.
Ну, даже в Java 8, long
и int
все еще подписаны, только некоторые методы относитесь к ним как к неподписанным. Если вы хотите написать unsigned 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 без знака 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
.
(отказ от ответственности: я работаю в компании за этими библиотеками)