Как использовать целое число без знака в 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: The long тип данных-это 64-разрядное целое число дополнения two. Подписанный long минимальное значение -263 и a максимальное значение 263-1. в Java SE 8 и более поздних, вы можете использовать long тип данных для представления 64-разрядной версии без знака long, который имеет минимальное значение 0 и максимальное значение 264-1. используйте этот тип данных, когда вам нужен диапазон значений шире, чем те, которые предоставляются int. Элемент Long класс также содержит методы, такие как compareUnsigned,divideUnsigned etc для поддержки арифметических операций для unsigned long.

однако, я не нахожу способ объявления длинного или целого числа без знака. Следующий код, например, дает сообщение об ошибке компилятора "литерал находится вне диапазона" (я использую 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 70

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.

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