Как использовать 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.

(Отказ от ответственности: я работаю в компании за этими библиотеками)