2009-04-10 9 views
21

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

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

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

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

+0

Есть ли конкретная причина, по которой вы используете короткий вместо int? Разве ваше значение CRC не указано? – akarnokd

ответ

54

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

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

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

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

+0

вы правы, это продвигает к int, поэтому сдвиг на 7 в порядке. Но << 32 не определено, поэтому ничего не делает. – CookieOfFortune

+0

Я нахожу, что «конвертирующий» буфер размером 8192 занимает почти всегда, когда отладчик подключен к устройству. Есть ли способ конвертировать весь буфер за один раз? –

+1

RE: «вам не нужно связывать себя узлами с битным смещением»; в моем опыте (и это довольно значительно, так как большая часть моей карьеры находится в комм), когда вы имеете дело с протоколами comms этого типа, вам лучше получить чертовски знакомые с бит-манипуляциями. –

20

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

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

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

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

+2

Вам не нужны приведения в int, что происходит неявно для операций &. – starblue

7

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

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

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

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

+0

Хотя, имея дело с 16-битными CRC, вам нужен только правильный битовый шаблон; не имеет значения, если подписано окончательное значение Java. –

+0

спасибо, я использовал '& 0x00FF' из первой строки для преобразования байта без знака в короткий. например, установив 0x87 на короткий, дал -121 вместо предполагаемого 135. – wrapperapps

2

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

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); 
0

вы можете преобразовать 2 байта на короткое замыкание в более удобном для восприятия и изящным способом.

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

Первый байт является самым значительным байт.

 Смежные вопросы

  • Нет связанных вопросов^_^