Quelle est la meilleure façon de contourner le fait que TOUS les octets Java sont signés ?

StackOverflow https://stackoverflow.com/questions/11088

  •  08-06-2019
  •  | 
  •  

Question

En Java, il n’existe pas d’octet non signé.

En travaillant avec du code de bas niveau, vous devez parfois travailler avec des octets dont les valeurs non signées sont supérieures à 128, ce qui amène Java à les interpréter comme un nombre négatif en raison du MSB utilisé pour le signe.

Quelle est la bonne façon de contourner ce problème ?(Dire de ne pas utiliser Java n'est pas une option)

Était-ce utile?

La solution

Lors de la lecture d'une valeur unique du tableau, copiez-la dans quelque chose comme un short ou un int et convertissez manuellement le nombre négatif en la valeur positive qu'il devrait être.

byte[] foobar = ..;
int value = foobar[10];
if (value < 0) value += 256 // Patch up the 'falsely' negative value

Vous pouvez effectuer une conversion similaire lors de l'écriture dans le tableau.

Autres conseils

Il est en fait possible de se débarrasser de l'instruction if et de l'addition si vous le faites ainsi.

byte[] foobar = ..;
int value = (foobar[10] & 0xff);

De cette façon, Java n'interprète pas l'octet comme un nombre négatif et inverse également le bit de signe sur l'entier.

Utiliser des ints est généralement préférable à l'utilisation de shorts car Java utilise de toute façon des valeurs 32 bits en interne (même pour les octets, sauf dans un tableau), donc l'utilisation de ints évitera une conversion inutile vers/depuis des valeurs courtes dans le bytecode.

Le mieux est probablement d’utiliser un entier plutôt qu’un octet.Il a la possibilité d'autoriser des nombres supérieurs à 128 sans avoir à créer un objet spécial pour remplacer l'octet.

Ceci est également suggéré par des personnes plus intelligentes que moi (tout le monde)

La meilleure façon de manipuler des bits/des octets non signés consiste à utiliser ints.Même s'ils sont signés, ils disposent de nombreux bits de rechange (32 au total) à traiter comme un octet non signé.De plus, tous les opérateurs mathématiques convertiront des nombres à précision fixe plus petits en int.Exemple:

short a = 1s;
short b = 2s;
int c = a + b; // the result is up-converted
short small = (short)c; // must cast to get it back to short

Pour cette raison, il est préférable de s'en tenir au nombre entier et de le masquer pour obtenir les bits qui vous intéressent.Exemple:

int a = 32;
int b = 128;
int foo = (a + b) | 255;

Voici quelques informations supplémentaires sur les types primitifs Java http://mindprod.com/jgloss/primitive.html

Une dernière remarque triviale, il existe un nombre à précision fixe non signé en Java.C'est le carboniser primitif.

Je sais que c'est une réponse très tardive, mais je suis tombé sur ce fil en essayant de faire exactement la même chose.Le problème consiste simplement à essayer de déterminer si un octet Java est >127.

La solution simple est :

if((val & (byte)0x80) != 0) { ... }

Si le vrai problème est > 128, il suffit d'ajouter une autre condition à cette instruction if pour faire l'affaire.

Je suppose que vous pourriez simplement utiliser un court-circuit pour les stocker.Pas très efficace, mais vraiment la seule option en dehors des efforts herculéens que j'ai vus.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top