355 votes

Déclarer un int non signé en Java

Existe-t-il un moyen de déclarer un int non signé en Java ?

La question peut aussi être formulée de cette manière : Quel est l'équivalent Java de unsigned ?

Pour vous donner le contexte, je regardais la mise en œuvre de Java de String.hashcode() . Je voulais tester la possibilité de collision si l'entier était un 32 unsigned int.

9 votes

Il n'existe pas de types non signés en Java.

1 votes

Cet article pourrait vous aider stackoverflow.com/a/4449161/778687

0 votes

353voto

Simeon Visser Points 30697

Java ne dispose pas d'un type de données pour entiers non signés .

Vous pouvez définir un long au lieu d'un int si vous devez stocker de grandes valeurs.

Vous pouvez également utiliser un entier signé comme s'il était non signé. L'avantage de représentation en complément à deux est que la plupart des opérations (telles que l'addition, la soustraction, la multiplication et le décalage à gauche) sont identiques au niveau binaire pour les entiers signés et non signés. Quelques opérations (division, décalage vers la droite, comparaison et coulage), cependant, sont différentes. À partir de Java SE 8, de nouvelles méthodes dans le module Integer vous permettent d'utiliser pleinement la classe int type de données pour effectuer des opérations arithmétiques non signées :

Dans Java SE 8 et les versions ultérieures, vous pouvez utiliser le type de données int pour représenter un nombre entier non signé de 32 bits, dont la valeur minimale est 0 et la valeur maximale 2^32-1. Utilisez la classe Integer pour utiliser le type de données int comme un entier non signé. Les méthodes statiques comme compareUnsigned , divideUnsigned ont été ajoutés à la classe Integer pour prendre en charge les opérations arithmétiques pour les entiers non signés.

Notez que int sont toujours signées lorsqu'elles sont déclarées, mais l'arithmétique non signée est désormais possible en utilisant ces méthodes dans le module de gestion de l'environnement. Integer classe.

11 votes

Pour être honnête, pour de nombreux projets, les exigences techniques ne sont pas aussi strictes et vous pouvez effectivement vous permettre de "gaspiller" de la mémoire de cette manière.

6 votes

Je sais, je comprends aussi l'objectif initial de Java. Mais par exemple, les Smartphones ne disposent pas de mémoire supplémentaire. Et ils utilisent généralement Java, pour autant que je sache. Mais bon, je ne veux pas commencer une guerre entre les programmeurs Java et les autres.

140 votes

Pour moi, ce n'est pas seulement un cas de gaspillage d'argent. Lorsque l'on travaille au niveau du bit, il est simplement plus facile de travailler avec les non signés.

74voto

baraber Points 970

2 votes

@stas J'ai du mal à comprendre l'utilité et l'importance de la possibilité d'utiliser des types de données non signés. D'après les différentes sources en ligne que j'ai lues, il semble que cela tourne autour de l'élargissement de la valeur maximale et de la garantie implicite par nature que c'est un nombre positif. Est-ce que je comprends bien, ou y a-t-il d'autres raisons majeures ? De plus, maintenant que le Integer en Java 8 permet d'utiliser des int non signés, la différence est juste en espace et en vitesse (puisqu'en C/C++ ils sont primitifs, alors qu'en Java, c'est un wrapper d'objet entier).

5 votes

Abdul - lorsque vous travaillez au niveau du bit (généralement parce que vous vous interfacez avec le matériel), vous avez besoin que les valeurs se comportent d'une certaine manière, c'est-à-dire qu'elles doivent passer de 11111111 à 00000000, etc. L'utilisation de valeurs signées à la place de valeurs non signées peut perturber les calculs CRC, etc. Ce n'est pas un problème majeur, mais une perte de temps.

3 votes

@Lorne K : en Java, int même s'ils sont signés. C'est en C/C++ que les non signés se retournent, mais les signés provoquent un "comportement indéfini" en cas de dépassement. Si le "roll over" est votre seule préoccupation, vous n'avez pas besoin de unsigned. Je suppose que c'est la raison pour laquelle les routines CRC, etc. fonctionnent en Java sans effort supplémentaire. Et c'est pourquoi la nouvelle API n'ajoute que l'analyse syntaxique, le formatage, les comparaisons, la division et le reste. Toutes les autres opérations, à savoir toutes les manipulations de bits, mais aussi l'addition, la soustraction, la multiplication, etc. font de toute façon ce qu'il faut.

71voto

Zsolt Safrany Points 1688

Le fait qu'une valeur dans un int soit signée ou non signée dépend de la manière dont les bits sont interprétés - Java interprète les bits comme une valeur signée (il ne dispose pas de primitives non signées).

Si vous avez un int que vous souhaitez interpréter comme une valeur non signée (par exemple, vous lisez un int à partir d'un fichier DataInputStream dont vous savez qu'elle doit être interprétée comme une valeur non signée), vous pouvez utiliser l'astuce suivante.

int fourBytesIJustRead = someObject.getInt();
long unsignedValue = fourBytesIJustRead & 0xffffffffL;

Notez qu'il est important que le littéral hexagonal soit un long littéral, et non un int littéral - d'où le 'L' à la fin.

3 votes

Pour moi, c'est la meilleure réponse... Mes données proviennent d'une carte NFC UID, qui peut avoir 4 ou 8 octets... Dans le cas de 4 octets, j'ai dû les convertir en un int non signé, et je ne pouvais pas utiliser ByteBuffer.getLong parce que ce n'était pas une donnée 64 bits. Merci.

0 votes

Pourquoi faut-il que ce soit long ? Tu ne peux pas simplement faire 0xFFFFFF et garder l'int ?

24voto

Lukas Eder Points 48046

Nous avions besoin de nombres non signés pour modéliser les nombres non signés de MySQL. TINYINT , SMALLINT , INT , BIGINT sur jOOQ C'est pourquoi nous avons créé jOOU Une bibliothèque minimaliste offrant des types enveloppants pour les nombres entiers non signés en Java. Exemple :

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 s'étendent java.lang.Number et peuvent être converties en types primitifs d'ordre supérieur et en BigInteger . J'espère que cela vous aidera.

(Clause de non-responsabilité : je travaille pour l'entreprise à l'origine de ces bibliothèques)

0 votes

Cela semble très pratique ! Merci de l'avoir mentionné :)

1voto

user2393012 Points 509

Cette fonction n'existe pas, mais si vous avez besoin d'une valeur supérieure à la valeur maximale + 5, vous pouvez utiliser BigInteger.

http://docs.oracle.com/javase/6/docs/api/java/math/BigInteger.html

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X