Equivalente Java de unsigned long long?

106

Em C ++, eu gostava de ter acesso a um inteiro não assinado de 64 bits, via unsigned long long intou via uint64_t. Agora, em Java, os longos são de 64 bits, eu sei. No entanto, eles estão assinados.

Existe um longo sem sinal (longo) disponível como um primitivo Java? Como eu uso isso?

onze81
fonte
4
NOTA A resposta aceita está desatualizada no Java 8 e posterior. Veja a Resposta da GigaStore para o novo recurso onde você pode pedir ao Java para considerar um número como não assinado. Não é para uso diário, mas é útil quando você precisa.
Basil Bourque

Respostas:

55

Eu não acredito nisso. Se você quiser ir maior do que um contrato assinado, acho que BigInteger é o único caminho a seguir (pronto para usar).

Sean Bright
fonte
17
Esta resposta está um pouco desatualizada (foi postada em 2009). A partir do Java 8 (lançado em março de 2014), há suporte para unsigned long. Veja um exemplo que postei abaixo como uma resposta.
Amr
140

A partir do Java 8, há suporte para unsigned long (não assinados de 64 bits). A maneira como você pode usá-lo é:

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

Para imprimi-lo, você não pode simplesmente imprimir l1, mas primeiro:

String l1Str = Long.toUnsignedString(l1)

Então

System.out.println(l1Str);
Amr
fonte
@ j10, Long ul1 = Long.parseUnsignedLong(objScannerInstance.next("\\d+"));Não é exatamente elegante porque não tem uma verificação de intervalo, mas permitiria que você extraísse entradas numéricas longas que, de outra forma, poderiam exceder o intervalo de um longo sinalizado. (Aproveita o fato de que Scanner::next(...)também pode aceitar um objeto Padrão ou um padrão String.)
Spencer D
é difícil.
Alex78191
12

Não, não há. Você terá que usar o longtipo de dados primitivo e lidar com problemas de assinatura ou usar uma classe como BigInteger.

Adam Rosenfield
fonte
7

Não, não há. Os designers de Java estão registrados dizendo que não gostavam de ints não assinados. Em vez disso, use um BigInteger . Veja esta pergunta para detalhes.

Paul Tomblin
fonte
22
Respeito Gosling pelo que ele fez, mas acho que sua defesa de nenhum ints não assinado é uma das desculpas mais idiotas que já ouvi. :-) Temos muuuuuito mais coisas complicadas em Java do que ints não assinados ... :-)
Brian Knoblauch
1
Gosling em JavaPolis 2007 deu um exemplo que confusamente não funciona para ints não assinados. Josh Bloch apontou que também não funciona para ints assinados. Inteiros de tamanho arbitrário ftw!
Tom Hawtin - tackline
2
@PP .: Não acho que seja possível definir regras sensatas que permitam interação livre entre tipos com e sem sinal quando pelo menos um deles tem comportamento de empacotamento definido. Dito isso, o byte sem sinal ou o curto sem sinal teria causado zero problemas, já que os bytes não interagem com outros tipos de qualquer maneira. Um problema maior é definir o comportamento de empacotamento para tipos que são usados ​​para representar números , diferente de ter tipos de empacotamento separados para aquelas raras ocasiões (como cálculos de código hash) quando o comportamento de empacotamento é realmente útil.
supercat
3
@PP .: Eu gostaria que os designers de linguagens reconhecessem a importância de distinguir números de anéis algébricos (o que são os tipos "inteiros que envolvem"). Qualquer número de tamanho deve ser convertido implicitamente em um anel de qualquer tamanho, mas os anéis só devem ser convertidos em números por meio da função ou por meio de typecast explícito para o mesmo número de tamanho . O comportamento de C, onde tipos sem sinal geralmente se comportam como anéis algébricos, mas às vezes se comportam como números, é provavelmente o pior de todos os mundos possíveis; Não posso culpar Gosling por querer evitar isso, embora ele tenha adotado uma abordagem totalmente errada para fazê-lo.
supercat de
6

Java 8 fornece um conjunto de operações longas sem sinal que permite que você trate diretamente essas variáveis ​​Long como longas sem sinal. Aqui estão algumas das mais usadas:

E adições, subtrações e multiplicações são as mesmas para longos com e sem sinal.

Keelar
fonte
2
Uma rápida olhada no código-fonte me diz para ser um pouco cauteloso com esses métodos. Quando os longos são de fato negativos (ou seja, há uma diferença do caso assinado), a classe BigInteger será usada. Isso significa que até 8 novos BigIntegers serão alocados, o que é bastante e definitivamente uma queda de desempenho.
Toonijn
4

Dependendo das operações que você pretende realizar, o resultado é praticamente o mesmo, com ou sem sinal. No entanto, a menos que esteja usando operações triviais, você acabará usando BigInteger.

Peter Lawrey
fonte
4

Por tempo não assinado, você pode usar a classe UnsignedLong da biblioteca Guava :

Suporta várias operações:

  • mais
  • menos
  • vezes
  • mod
  • dividido por

O que parece faltar no momento são os operadores de deslocamento de bytes. Se precisar deles, você pode usar o BigInteger do Java.

Andrejs
fonte
3

Java não possui tipos não assinados. Como já mencionado, incure a sobrecarga do BigInteger ou use JNI para acessar o código nativo.

basszero
fonte
15
char é um valor de 16 bits sem sinal;)
Peter Lawrey
2

O pacote org.apache.axis.types tem um

Classe UnsignedLong.

para maven:

<dependency>
    <groupId>org.apache.axis</groupId>
    <artifactId>axis</artifactId>
    <version>1.4</version>
</dependency>
user637338
fonte
0

Parece que no Java 8 alguns métodos foram adicionados ao Long para tratar o antigo e bom [assinado], desde que não assinado. Parece uma solução alternativa, mas às vezes pode ajudar.

Mikalai Sabel
fonte