Java équivalent de unsigned long long?

106

En C ++, j'ai apprécié avoir accès à un entier non signé 64 bits, via unsigned long long int ou via uint64_t. Maintenant, en Java, les longs sont 64 bits, je sais. Cependant, ils sont signés.

Un long (long) non signé est-il disponible en tant que primitive Java? Comment l'utiliser?

onze81
la source
4
REMARQUE La réponse acceptée est obsolète à partir de Java 8 et versions ultérieures. Voir la réponse de GigaStore pour la nouvelle fonctionnalité où vous pouvez demander à Java de considérer un nombre comme non signé. Pas pour un usage quotidien, mais pratique lorsque vous en avez besoin.
Basil Bourque

Réponses:

55

Je ne crois pas. Une fois que vous voulez aller plus grand qu'un long signé, je pense que BigInteger est la seule solution ( prête à l' emploi ).

Sean Bright
la source
17
Cette réponse est un peu dépassée (elle a été publiée en 2009). À partir de Java 8 (publié en mars 2014), il existe un support pour unsigned long. Consultez un exemple que j'ai publié ci-dessous comme réponse.
Amr
140

À partir de Java 8, il existe un support pour unsigned long (non signé 64 bits). La façon dont vous pouvez l'utiliser est:

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

Pour l'imprimer, vous ne pouvez pas simplement imprimer l1, mais vous devez d'abord:

String l1Str = Long.toUnsignedString(l1)

ensuite

System.out.println(l1Str);
Amr
la source
@ j10, Long ul1 = Long.parseUnsignedLong(objScannerInstance.next("\\d+"));Pas vraiment élégant car il manque une vérification de plage, mais cela vous permettrait de tirer de longues entrées numériques qui, autrement, dépasseraient la plage d'un long signé. (Exploite le fait qu'il Scanner::next(...)peut également accepter un objet Pattern ou un motif String.)
Spencer D
c'est difficile.
Alex78191
12

Non, il n'y en a pas. Vous devrez utiliser le longtype de données primitif et gérer les problèmes de signature, ou utiliser une classe telle que BigInteger.

Adam Rosenfield
la source
7

Non, il n'y en a pas. Les concepteurs de Java ont déclaré qu'ils n'aimaient pas les entiers non signés. Utilisez plutôt un BigInteger . Voir cette question pour plus de détails.

Paul Tomblin
la source
22
Je respecte Gosling pour ce qu'il a fait, mais je pense que sa défense de non-signés est l'une des excuses les plus stupides que j'aie jamais entendues. :-) Nous avons waaaay plus de choses loufoques en Java que des entiers non signés ... :-)
Brian Knoblauch
1
Gosling à JavaPolis 2007 a donné un exemple qui ne fonctionne pas pour les entiers non signés. Josh Bloch a souligné que cela ne fonctionne pas non plus pour les entiers signés. Entiers de taille arbitraire ftw!
Tom Hawtin - tackline
2
@PP .: Je ne pense pas qu'il soit possible de définir des règles sensées permettant une interaction libre entre les types signés et non signés lorsqu'au moins l'un d'entre eux a défini un comportement d'encapsulation. Cela étant dit, l'octet non signé ou le court non signé n'aurait causé aucun problème puisque les octets n'interagissent de toute façon pas avec d'autres types. Un problème plus important est d'avoir défini un comportement d'encapsulation pour les types qui sont utilisés pour représenter des nombres , par opposition à avoir des types d'encapsulation séparés pour ces rares occasions (comme les calculs de hashcode) lorsque le comportement d'encapsulation est réellement utile.
supercat
3
@PP .: Je souhaite que les concepteurs de langage reconnaissent l'importance de distinguer les nombres des anneaux algébriques (ce que sont les types "d'entiers enveloppants"). Tout numéro de taille doit être implicitement converti en une bague de toute taille, mais les bagues ne doivent être converties en nombres que via une fonction ou via un typage explicite vers le même numéro de taille . Le comportement de C, où les types non signés se comportent généralement comme des anneaux algébriques mais se comportent parfois comme des nombres, est probablement le pire de tous les mondes possibles; Je ne peux pas reprocher à Gosling de vouloir éviter cela, bien qu'il ait totalement adopté la mauvaise approche pour le faire.
supercat
6

Java 8 fournit un ensemble d'opérations longues non signées qui vous permettent de traiter directement ces variables Long comme non signées Long, en voici quelques-unes couramment utilisées:

Et les additions, soustractions et multiplications sont les mêmes pour les longs signés et non signés.

keelar
la source
2
Un rapide coup d'œil dans le code source me dit d'être un peu prudent avec ces méthodes. Lorsque les longs sont effectivement négatifs (c'est-à-dire qu'il y a une différence avec le cas signé), la classe BigInteger sera utilisée. Cela signifie que jusqu'à 8 nouveaux BigIntegers seront alloués, c'est beaucoup et certainement une baisse de performance.
Toonijn
4

Selon les opérations que vous envisagez d'effectuer, le résultat est sensiblement le même, signé ou non. Cependant, à moins que vous n'utilisiez des opérations triviales, vous finirez par utiliser BigInteger.

Peter Lawrey
la source
4

Pour unsigned long, vous pouvez utiliser la classe UnsignedLong de la bibliothèque Guava :

Il prend en charge diverses opérations:

  • plus
  • moins
  • fois
  • mod
  • divisé par

Ce qui semble manquer pour le moment, ce sont les opérateurs de décalage d'octets. Si vous en avez besoin, vous pouvez utiliser BigInteger de Java.

Andrejs
la source
3

Java n'a pas de types non signés. Comme déjà mentionné, augmentez la charge de BigInteger ou utilisez JNI pour accéder au code natif.

basszero
la source
15
char est une valeur 16 bits non signée;)
Peter Lawrey
2

Le package org.apache.axis.types a un

UnsignedLong classe.

pour maven:

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

On dirait que dans Java 8, certaines méthodes sont ajoutées à Long pour traiter l'ancien bon [signé] tant que non signé. Cela semble être une solution de contournement, mais peut parfois aider.

Mikalai Sabel
la source