2 байта к короткой Java - PullRequest
28 голосов
/ 10 апреля 2009

Я читаю пакет длиной 133 из последовательного порта, последние 2 байта содержат значения CRC, значение 2 байта, которое я сделал единичным (думаю, коротким), используя java. это то, что я сделал,

short high=(-48 & 0x00ff);
short low=80;

short c=(short) ((high<<8)+low);

но я не получаю правильный результат, это проблема, потому что подписано ценится? как я могу решить эту проблему, плз, помогите мне, я в беде

Ответы [ 5 ]

58 голосов
/ 10 апреля 2009

Помните, что вам не нужно связывать себя узлами со сдвигом бит, если вы не слишком знакомы с деталями. Вы можете использовать ByteBuffer, чтобы помочь вам:

ByteBuffer bb = ByteBuffer.allocate(2);
bb.order(ByteOrder.LITTLE_ENDIAN);
bb.put(firstByte);
bb.put(secondByte);
short shortVal = bb.getShort(0);

И наоборот, вы можете поставить короткий, а затем вытащить байты.

Кстати, побитовые операции автоматически переводят операнды как минимум на ширину целого числа. На самом деле нет понятия «не разрешено сдвигать байт больше, чем на 7 бит», и других слухов, которые, кажется, вращаются.

26 голосов
/ 10 апреля 2009

При преобразовании байтовых значений из потока в числовые значения в Java вы должны быть очень осторожны с расширением знака. Есть ловушка с отрицательными числами (значения от (без знака) 128-255).

Попробуйте это (это работает, если hi и lo - любой целочисленный тип Java):

short val=(short)(((hi & 0xFF) << 8) | (lo & 0xFF));

Я считаю, что в этих случаях лучше указывать скобки.

9 голосов
/ 08 июля 2009

Остальные ответы в порядке, но я бы хотел выделить тип:

short high=(-48 & 0x00ff);
short low=80;

int c= ((high & 0xFF) << 8) | (low & 0xFF);

Тип short может представлять значения в диапазоне от -32768 до 32767. 53328 не может быть приятно сохранен вкратце, вместо этого используйте int, поскольку он позволяет хранить значение без знака до ~ 10 9 Так что не уменьшайте выражение до короткого, так как оно даст вам подписанное значение.

6 голосов
/ 06 июля 2016

Это происходит при попытке объединить байты (очень тонко)

byte b1 = (byte) 0xAD;
byte b2 = (byte) 0xCA;
short s = (short) (b1<<8 | b2);

Выше приведено 0xFFCA, что неправильно. Это потому, что b2 отрицателен (тип байта подписан!), Что означает, что когда он будет преобразован в тип int для побитового | операции, он будет дополнен слева 0xF!

Следовательно, вы должны помнить, чтобы маскировать заполненные байты так, чтобы они точно были равны нулю:

short s = (short) (b1<<8 | b2 & 0xFF);
2 голосов
/ 27 февраля 2018

Вы можете преобразовать 2 байта в короткий более читаемым и элегантным способом.

short s = ByteBuffer.wrap(new byte[]{0x01, 0x02}).getShort();
// now s equals 258 = 256 + 2

Первый байт - самый старший байт.

...