Java-эквивалент unsigned long long?

106

В C ++ мне нравилось иметь доступ к 64-битному целому числу без знака, через unsigned long long intили через uint64_t. Я знаю, что в Java длинные строки - это 64 бита. Однако они подписаны.

Доступен ли беззнаковый длинный (длинный) как примитив Java? Как мне его использовать?

одиннадцать81
источник
4
ПРИМЕЧАНИЕ . Принятый ответ устарел для Java 8 и новее. См. Ответ GigaStore о новой функции, в которой вы можете попросить Java рассматривать число как беззнаковое. Не для повседневного использования, но под рукой, когда это необходимо.
Basil Bourque

Ответы:

55

Я так не верю. Если вы захотите выйти за рамки подписанного лонг, я думаю, что BigInteger - единственный (нестандартный) способ пойти.

Шон Брайт
источник
17
Этот ответ немного устарел (опубликован в 2009 году). Начиная с Java 8 (выпущенной в марте 2014 г.), есть поддержка unsigned long. Посмотрите пример, который я опубликовал ниже в качестве ответа.
Амр
140

Начиная с Java 8, есть поддержка unsigned long (беззнаковые 64 бита). Вы можете использовать это следующим образом:

Long l1 = Long.parseUnsignedLong("17916881237904312345");

Чтобы распечатать его, вы не можете просто распечатать l1, но вам нужно сначала:

String l1Str = Long.toUnsignedString(l1)

затем

System.out.println(l1Str);
Амр
источник
@ j10, Long ul1 = Long.parseUnsignedLong(objScannerInstance.next("\\d+"));не совсем элегантный, потому что в нем отсутствует проверка диапазона, но он позволит вам вводить длинные числовые входы, которые в противном случае могли бы выйти за пределы диапазона длинного числа со знаком. (Использует тот факт, что Scanner::next(...)также может принимать либо объект Pattern, либо шаблон String.)
Spencer D
это трудно.
Alex78191 06
12

Нет, нет. Вам придется использовать примитивный longтип данных и решать проблемы подписи или использовать такой класс, как BigInteger.

Адам Розенфилд
источник
7

Нет, нет. Разработчики Java официально заявляют, что им не нравятся целые числа без знака. Вместо этого используйте BigInteger . См. Этот вопрос для подробностей.

Пол Томблин
источник
22
Я уважаю Гослинга за то, что он сделал, но я думаю, что его защита отсутствия неподписанных целочисленных значений - одно из самых глупых оправданий, которые я когда-либо слышал. :-) У нас в Java гораздо больше шатких вещей, чем беззнаковые целые числа ... :-)
Брайан Ноблауч
1
Гослинг на JavaPolis 2007 привел пример, который по непонятной причине не работает с целыми числами без знака. Джош Блох указал, что это не работает и для подписанных int. Целые числа произвольного размера ftw!
Том Хотин - tackline
2
@PP .: Я не думаю, что возможно определить разумные правила, которые разрешают свободное взаимодействие между подписанными и неподписанными типами, когда хотя бы один из них определил поведение упаковки. При этом беззнаковый байт или беззнаковое короткое замыкание вызвало бы ноль проблем, поскольку байты в любом случае не взаимодействуют с другими типами. Более серьезной проблемой является определение поведения упаковки для типов, которые используются для представления чисел , в отличие от наличия отдельных типов упаковки для тех редких случаев (например, вычислений хэш-кода), когда поведение упаковки действительно полезно.
supercat
3
@PP .: Я бы хотел, чтобы разработчики языков осознавали важность различения чисел от алгебраических колец (что такое «обертывающие целочисленные» типы). Число любого размера должно неявно преобразовываться в кольцо любого размера, но кольца должны преобразовываться в числа только через функцию или через явное приведение типов к тому же числу размера . Поведение языка C, в котором беззнаковые типы обычно ведут себя как алгебраические кольца, но иногда как числа, вероятно, наихудшее из всех возможных миров; Я не могу винить Гослинга в том, что он хотел этого избежать, хотя он сделал для этого совершенно неправильный подход.
supercat
6

Java 8 предоставляет набор длинных беззнаковых операций, которые позволяют вам напрямую обрабатывать эти длинные переменные как беззнаковые длинные, вот некоторые из наиболее часто используемых:

И сложение, вычитание и умножение одинаковы для длинных чисел со знаком и без знака.

килевой
источник
2
Беглый взгляд на исходный код подсказывает мне, что нужно быть осторожнее с этими методами. Когда длинные значения действительно отрицательны (т. Е. Есть отличие от случая со знаком), будет использоваться класс BigInteger. Это означает, что будет выделено до 8 новых BigInteger, это довольно много и определенно снижает производительность.
Toonijn
4

В зависимости от операций, которые вы собираетесь выполнить, результат во многом будет одинаковым, со знаком или без знака. Однако, если вы не используете тривиальные операции, вы в конечном итоге будете использовать BigInteger.

Питер Лоури
источник
4

Для unsigned long вы можете использовать класс UnsignedLong из библиотеки Guava :

Он поддерживает различные операции:

  • плюс
  • минус
  • раз
  • мод
  • деленное на

На данный момент кажется, что не хватает операторов байтового сдвига. Если они вам нужны, вы можете использовать BigInteger из Java.

Андрейс
источник
3

В Java нет беззнаковых типов. Как уже упоминалось, используйте накладные расходы BigInteger или используйте JNI для доступа к машинному коду.

басовый
источник
15
char - это беззнаковое 16-битное значение;)
Питер Лоури 03
2

В пакете org.apache.axis.types есть

UnsignedLong класс.

для maven:

<dependency>
    <groupId>org.apache.axis</groupId>
    <artifactId>axis</artifactId>
    <version>1.4</version>
</dependency>
user637338
источник
0

Похоже, что в Java 8 в Long добавлены некоторые методы для обработки старого доброго [подписанного] долго без знака. Похоже на обходной путь, но иногда может помочь.

Николай Сабель
источник