web-dev-qa-db-fra.com

Non signé longtemps en Java

Actuellement, j'utilise des valeurs signées, -2 ^ 63 à 2 ^ 63-1. Maintenant, j'ai besoin de la même plage (2 * 2 ^ 64), mais avec des valeurs positives uniquement. J'ai trouvé les documentations Java mentionnant long non signé, ce qui convient à cette utilisation.

J'ai essayé de déclarer 2 ^ 64 à un objet wrapper long, mais il perd toujours les données. En d'autres termes, il ne capture que jusqu'au Long.MAX_VALUE; il me manque donc clairement quelque chose. Est-ce que BigInteger est le signe signé pris en charge par Java?

Existe-t-il une définition ou un indicateur sur la façon de le déclarer et de l’utiliser?

5
SpreeTheGr8

Java n'a pas de type long non signé, mais vous pouvez traiter les entiers signés du complément à deux éléments 64 bits signés (c'est-à-dire long) comme non signés si vous y êtes attentif. 

De nombreuses opérations entières primitives sont "agnostiques de signe"; par exemple. vous pouvez utiliser l'addition, la soustraction et la multiplication de primitives Java, et obtenir la "bonne" réponse pour un nombre non signé représenté à l'aide de long.

Pour d'autres opérations telles que la division et la comparaison, la classe Long fournit la méthode divideUnsigned et compareUnsigned qui donnera les résultats corrects pour les nombres non signés représentés par les valeurs long

(Ces opérations ont été ajoutées à Java 8. Avant cela, vous pouviez utiliser des bibliothèques tierces; par exemple, des méthodes statiques dans com.google.common.primitives.UnsignedLongs .)

5
Stephen C

En Java 8, le support unsigned long a été introduit. Ce sont quand même des longs, mais le signe n’a aucune incidence sur l’addition et la soustraction. Pour diviser et comparer, vous avez des méthodes dédiées dans Long. En outre, vous pouvez effectuer les opérations suivantes:

Long l1 = Long.parseUnsignedLong("12345678901234567890");
String l1Str = Long.toUnsignedString(l1)

BigInteger est un peu différent. Il peut garder des nombres énormes. Il les stocke sous le nom int[] et prend en charge l'arithmétique. 

3
xenteros

Si l'utilisation d'une bibliothèque tierce est une option, il existe jOOU (une bibliothèque dérivée de jOOQ ), qui propose des types d'encapsuleur pour les nombres entiers non signés en Java. Ce n'est pas exactement la même chose que d'avoir un support de type primitif (et donc de code octet) pour les types non signés, mais cela reste peut-être suffisant pour votre cas d'utilisation.

import static org.joou.Unsigned.*;

// and then...
UByte    b = ubyte(1);
UShort   s = ushort(1);
UInteger i = uint(1);
ULong    l = ulong(1);

Tous ces types étendent Java.lang.Number et peuvent être convertis en types primitifs d'ordre supérieur et BigInteger. Dans votre cas, les versions antérieures de jOU ont simplement stocké la valeur longue non signée dans une variable BigInteger. La version 0.9.3 effectue des décalages de bits sympas pour s’ajuster à la valeur d’une long ordinaire.

(Avertissement: je travaille pour l'entreprise derrière ces bibliothèques)

0
Lukas Eder