je lis 133 paquets de longueur depuis serialport, les 2 derniers octets contiennent des valeurs CRC, la valeur de 2 octets que j'ai rendue unique (courte je pense) en utilisant Java. c'est ce que j'ai fait,
short high=(-48 & 0x00ff);
short low=80;
short c=(short) ((high<<8)+low);
mais je n'obtiens pas un résultat correct, est-ce un problème car signé valorisé? comment puis-je résoudre ce problème, plz aidez-moi, je suis en difficulté
N'oubliez pas que vous n'avez pas à vous nouer avec des nœuds avec un peu de décalage si vous n'êtes pas trop familier avec les détails. Vous pouvez utiliser un ByteBuffer pour vous aider:
ByteBuffer bb = ByteBuffer.allocate(2);
bb.order(ByteOrder.LITTLE_ENDIAN);
bb.put(firstByte);
bb.put(secondByte);
short shortVal = bb.getShort(0);
Et vice versa, vous pouvez mettre un court, puis extraire des octets.
Soit dit en passant, les opérations au niveau du bit promeuvent automatiquement les opérandes à au moins la largeur d'un int. Il n'y a vraiment aucune notion de "ne pas être autorisé à décaler un octet de plus de 7 bits" et d'autres rumeurs qui semblent circuler.
Lors de la conversion des valeurs d'octets d'un flux en valeurs numériques dans Java vous devez être très prudent avec l'extension de signe. Il y a un piège avec des nombres négatifs (valeurs de (non signé) 128-255).
Essayez ceci (cela fonctionne si hi et lo sont quelconques Java type entier):
short val=(short)(((hi & 0xFF) << 8) | (lo & 0xFF));
Je trouve qu'il vaut mieux être explicite avec les parenthèses dans ces cas.
Les autres réponses sont OK, mais je voudrais mettre l'accent sur le type:
short high=(-48 & 0x00ff);
short low=80;
int c= ((high & 0xFF) << 8) | (low & 0xFF);
Le type short
peut représenter des valeurs entre -32768 et 32767. 53328 ne peut pas être bien stocké en bref, utilisez plutôt int
car il vous permet de stocker des valeurs non signées jusqu'à ~ 109 Donc, ne réduisez pas l'expression à court car cela vous rapportera la valeur signée.
Cela se produit lorsque vous essayez de concaténer des octets (très subtil)
byte b1 = (byte) 0xAD;
byte b2 = (byte) 0xCA;
short s = (short) (b1<<8 | b2);
Ce qui précède produit 0xFFCA, ce qui est faux. En effet, b2 est négatif (le type d'octet est signé!), Ce qui signifie que lorsqu'il sera converti en type int pour le bit | opération, il sera rempli à gauche avec 0xF!
Par conséquent, vous devez vous rappeler de masquer les octets remplis afin qu'ils soient définitivement nuls:
short s = (short) (b1<<8 | b2 & 0xFF);
Vous pouvez convertir 2 octets en un short d'une manière plus lisible et élégante.
short s = ByteBuffer.wrap(new byte[]{0x01, 0x02}).getShort();
// now s equals 258 = 256 + 2
Le premier octet est l'octet le plus significatif.