Peut-on faire un byte non signé en Java
j'essaie de convertir un octet signé en non signé. Le problème est que les données que je reçois ne sont pas signées et que Java ne supporte pas les bytes non signés, donc quand il lit les données il les traite comme signées.
j'ai essayé de le convertir par la solution suivante que j'ai obtenue du débordement de la pile.
public static int unsignedToBytes(byte a)
{
int b = a & 0xFF;
return b;
}
mais quand encore il est converti en octet, je reçois les mêmes données signées. J'essaie d'utiliser ces données comme paramètre pour une fonction de Java qui accepte seulement un octet comme paramètre, donc je ne peux pas utiliser un autre type de données. Comment puis-je résoudre ce problème?
14 réponses
Je ne suis pas sûr de comprendre votre question.
je viens d'essayer ceci et pour byte -12 (valeur signée) il retourne un entier 244 (équivalent à une valeur de byte non signée mais tapé comme un int
):
public static int unsignedToBytes(byte b) {
return b & 0xFF;
}
public static void main(String[] args) {
System.out.println(unsignedToBytes((byte) -12));
}
C'est ce que tu veux faire?
Java ne permet pas d'exprimer 244 comme une valeur byte
, comme C. pour exprimer des entiers positifs au-dessus de Byte.MAX_VALUE
(127) vous devez utiliser un autre type d'entier, comme short
, int
ou long
.
le fait que les primitifs soient signés en Java n'est pas pertinent pour la façon dont ils sont représentés en mémoire / transit - un octet est simplement 8 bits et que vous l'interprétiez comme une portée signée ou non dépend de vous. Il n'y a pas de magie drapeau pour dire "c'est signé" ou "ce n'est pas signé".
comme les primitives sont signées, le compilateur Java vous empêchera d'attribuer une valeur supérieure à +127 à un octet (ou inférieure à-128). Cependant, il n'y a rien pour vous arrêter de passer un int (ou court) pour y parvenir:
int i = 200; // 0000 0000 0000 0000 0000 0000 1100 1000 (200)
byte b = (byte) 200; // 1100 1000 (-56 by Java specification, 200 by convention)
/*
* Will print a negative int -56 because upcasting byte to int does
* so called "sign extension" which yields those bits:
* 1111 1111 1111 1111 1111 1111 1100 1000 (-56)
*
* But you could still choose to interpret this as +200.
*/
System.out.println(b); // "-56"
/*
* Will print a positive int 200 because bitwise AND with 0xFF will
* zero all the 24 most significant bits that:
* a) were added during upcasting to int which took place silently
* just before evaluating the bitwise AND operator.
* So the `b & 0xFF` is equivalent with `((int) b) & 0xFF`.
* b) were set to 1s because of "sign extension" during the upcasting
*
* 1111 1111 1111 1111 1111 1111 1100 1000 (the int)
* &
* 0000 0000 0000 0000 0000 0000 1111 1111 (the 0xFF)
* =======================================
* 0000 0000 0000 0000 0000 0000 1100 1000 (200)
*/
System.out.println(b & 0xFF); // "200"
/*
* You would typically do this *within* the method that expected an
* unsigned byte and the advantage is you apply `0xFF` only once
* and than you use the `unsignedByte` variable in all your bitwise
* operations.
*
* You could use any integer type longer than `byte` for the `unsignedByte` variable,
* i.e. `short`, `int`, `long` and even `char`, but during bitwise operations
* it would get casted to `int` anyway.
*/
void printUnsignedByte(byte b) {
int unsignedByte = b & 0xFF;
System.out.println(unsignedByte); // "200"
}
il n'y a pas D'octets primitifs non signés en Java. La chose habituelle est de le mouler en plus grand type:
int anUnsignedByte = (int) aSignedByte & 0xff;
le langage Java ne fournit rien comme le mot-clé unsigned
. Un byte
selon la spécification de la langue représente une valeur entre -128 - 127. Par exemple, si un byte
est ajouté à un int
, Java interprétera le premier bit comme le signe et utilisera extension du signe .
cela dit, rien ne vous empêche de voir un byte
simplement comme 8 bits et d'interpréter ces bits comme une valeur entre 0 et 255. Gardez juste à l'esprit qu'il n'y a rien que vous puissiez faire pour forcer votre interprétation sur la méthode de quelqu'un d'autre. Si une méthode accepte un byte
, alors cette méthode accepte une valeur entre -128 et 127 sauf indication contraire explicite.
voici quelques conversions / manipulations utiles pour votre confort:
Conversions à / de int
// From int to unsigned byte
int i = 200; // some value between 0 and 255
byte b = (byte) i; // 8 bits representing that value
// From unsigned byte to int
byte b = 123; // 8 bits representing a value between 0 and 255
int i = b & 0xFF; // an int representing the same value
(ou, si vous êtes sur Java 8+, utilisez Byte.toUnsignedInt
.)
Analyse / mise en forme
la meilleure façon est d'utiliser les conversions ci-dessus:
// Parse an unsigned byte
byte b = (byte) Integer.parseInt("200");
// Print an unsigned byte
System.out.println("Value of my unsigned byte: " + (b & 0xFF));
arithmétique
L'2-compléter la représentation "fonctionne" pour l'addition, la soustraction et de la multiplication:
// two unsigned bytes
byte b1 = (byte) 200;
byte b2 = (byte) 15;
byte sum = (byte) (b1 + b2); // 215
byte diff = (byte) (b1 - b2); // 185
byte prod = (byte) (b2 * b2); // 225
Division exige la conversion manuelle de opérandes:
byte ratio = (byte) ((b1 & 0xFF) / (b2 & 0xFF));
je pense que les autres réponses ont couvert la représentation de la mémoire et la façon dont vous les gérez dépend du contexte dans lequel vous prévoyez de les utiliser. J'ajouterai que Java 8 a ajouté un support pour traiter les types non signés . Dans ce cas, vous pourriez utiliser Byte.toUnsignedInt
int unsignedInt = Byte.toUnsignedInt(myByte);
Une note de côté, si vous voulez l'imprimer, vous pouvez juste dire
byte b = 255;
System.out.println((b < 0 ? 256 + b : b));
Adamski a fourni la meilleure réponse, mais elle n'est pas tout à fait complète, alors lisez sa réponse, car il explique les détails que je ne suis pas.
si vous avez une fonction système qui nécessite qu'un octet non signé lui soit passé, vous pouvez passer un octet signé car il le traitera automatiquement comme un octet non signé.
donc si une fonction système nécessite quatre octets, par exemple, 192 168 0 1 comme octets non signés, vous pouvez passer -64 -88 0 1, et la fonction fonctionnera toujours, parce que le fait de les passer à la fonction de l'onu-les signer.
cependant, il est peu probable que vous ayez ce problème car les fonctions du système sont cachées derrière les classes pour la compatibilité entre les plates-formes, bien que certaines de java.io read methods return unsighed bytes as an int.
si vous voulez que cela fonctionne, essayez d'écrire des octets signés dans un fichier et relisez-les en octets non signés.
si vous avez une fonction qui doit passer un byte signé, que voulez-vous qu'elle fasse si vous passez un byte non signé?
pourquoi ne pouvez-vous pas utiliser un autre type de données?
normalement vous pouvez utiliser un byte comme un byte non signé avec des traductions simples ou aucune. Tout dépend de comment il est utilisé. Vous devez clarifier ce que vous en faites.
bien qu'il puisse sembler ennuyeux (venant de C) que Java n'ait pas inclus un octet non signé dans la langue, ce n'est pas grand chose car une simple opération" b & 0xFF " produit la valeur non signée pour un octet B (signé) dans les situations (rares) qu'il est réellement nécessaire. Les bits ne changent pas réellement -- juste l'interprétation (qui est importante seulement quand on fait par exemple quelques opérations mathématiques sur les valeurs).
si vous pensez que vous cherchez quelque chose comme ça.
public static char toUnsigned(byte b) {
return (char) (b >= 0 ? b : 256 + b);
}
il n'y a pas de byte non signé en Java, mais si vous voulez afficher un byte, vous pouvez le faire,
int myInt = 144;
byte myByte = (byte) myInt;
char myChar = (char) (myByte & 0xFF);
System.out.println("myChar :" + Integer.toHexString(myChar));
sortie:
myChar : 90
pour plus d'informations, veuillez cocher Comment afficher une valeur hexadécimale/octet en Java .
selon les limitations en Java, un octet non signé est presque impossible dans le format de type de données actuel. Vous pouvez choisir d'autres bibliothèques d'une autre langue pour ce que vous mettez en œuvre et ensuite vous pouvez les appeler en utilisant JNI .
si vous voulez des octets non signés en Java, soustrayez simplement 256 du numéro qui vous intéresse. Il produira complément de two avec une valeur négative, qui est le nombre désiré en octets non signés.
exemple:
int speed = 255; //Integer with the desired byte value
byte speed_unsigned = (byte)(speed-256);
//This will be represented in two's complement so its binary value will be 1111 1111
//which is the unsigned byte we desire.
vous devez utiliser de tels piratages sales lorsque vous utilisez leJOS pour programmer la brique NXT .
Oui et non. Ive été de creuser autour de ce problème. Comme je comprends ceci:
le fait est que java a signé interger -128 à 127.. Il est possible de présenter un non signé en java avec:
public static int toUnsignedInt(byte x) {
return ((int) x) & 0xff;
}
si par exemple vous ajoutez -12 nombre signé à être non signé vous obtenez 244. Mais vous pouvez utiliser ce nombre à nouveau dans signed, il doit être décalé vers signed et il sera à nouveau -12.
Si vous essayez d'ajouter 244 à java vous aurez outOfIndexException.
santé..