Преобразовать 2 байта в число

У меня есть элемент управления с байтовым массивом.

Время от времени появляются два байта, которые сообщают мне некоторую информацию о количестве будущих элементов в массиве.

Итак, в качестве примера я мог бы:

...
...
Item [4] = 7
Item [5] = 0
...
...

Ценность этого явно равна 7.

Но как насчет этого?

...
...
Item [4] = 0
Item [5] = 7
...
...

Есть идеи, что это означает (как обычный int)?

Я перешел на двоичный код и подумал, что это может быть 11100000000, что равно 1792. Но я не знаю, как это работает на самом деле (т.е. использует ли он все 8 элементов для байта).

Есть ли способ узнать это без тестирования?

Примечание: я использую C # 3.0 и Visual Studio 2008.


person Vaccano    schedule 17.04.2010    source источник
comment
Похоже, вы просите нас реконструировать некоторые сериализованные данные. Это будет сложно. Вы могли бы хотя бы опубликовать несколько примеров полного байтового массива и того, что ему соответствует, для трех или четырех простых примеров. Но почему вы вообще хотите это знать? Какую проблему ты пытаешься решить?   -  person Mark Byers    schedule 18.04.2010
comment
Я пытаюсь расшифровать массив байтов, возвращаемый элементом управления Signature в элементе управления OpenNETCF, чтобы я мог повернуть его на 180 градусов. См. Этот вопрос stackoverflow.com/questions/2657388/ для подробнее.   -  person Vaccano    schedule 18.04.2010


Ответы (6)


BitConverter может легко преобразовать два байта в двухбайтовое целочисленное значение:

// assumes byte[] Item = someObject.GetBytes():
short num = BitConverter.ToInt16(Item, 4); // makes a short 
    // out of Item[4] and Item[5]
person MusiGenesis    schedule 18.04.2010
comment
@Macho Matt: если вы хотите прокомментировать уже принятый ответ, лучше оставить комментарий, чем редактировать сам вопрос. Кроме того, ваша точка зрения не была строго точной - не имеет значения, является ли компьютерная система с прямым порядком байтов или с прямым порядком байтов, это имеет значение только в том случае, если система, которая изначально создала массив байтов, имеет другой порядок байтов, чем система, на которой работает .NET. код здесь. - person MusiGenesis; 27.06.2011
comment
Это предполагает, что старший бит двоичного представления этих двух байтов является битом знака (1 = -ve, 0 = + ve). Если это не так, т.е. если число беззнаковое, то вам нужно использовать это. ushort num = BitConverter.ToUInt16 (Элемент, 4). Также имейте в виду, что у этого байта будет байт с индексом 5 в качестве первого байта (наиболее значимого байта), если ваша архитектура является прямым порядком байтов. Прочтите reinventingthewheel.azurewebsites.net/TwosComplementTut.aspx для получения дополнительной информации о знаковом бите. - person David Klempfner; 04.03.2015

Двухбайтовое число имеет младший и старший байт. Старший байт стоит в 256 раз дороже младшего:

value = 256 * high + low;

Итак, для high = 0 и low = 7 значение равно 7. Но для high = 7 и low = 0 значение становится 1792.

Это, конечно, предполагает, что число является простым 16-битным целым числом. Если это что-то более интересное, вышеперечисленного будет недостаточно. Тогда вам нужно больше знаний о том, как кодируется число, чтобы его расшифровать.

Порядок, в котором появляются старший и младший байты, определяется порядком байтов байтового потока. При обратном порядке байтов вы увидите сначала высокое значение, а затем низкое (по более низкому адресу), а при обратном порядке байтов - наоборот.

person unwind    schedule 17.04.2010
comment
Также стоит отметить: (high << 8) | low - person GeReV; 18.04.2010

Вы говорите: «Очевидно, это значение 7», но это полностью зависит от кодировки. Если мы примем байты полной ширины, то с прямым порядком байтов - да; 7, 0 равно 7. Но с прямым порядком байтов это не так.

Для little-endian вам нужно

int i = byte[i] | (byte[i+1] << 8);

и для прямого порядка байтов:

int i = (byte[i] << 8) | byte[i+1];

Но доступны и другие схемы кодирования; например, в некоторых схемах используется 7-битная арифметика с 8-м битом в качестве бита продолжения. Некоторые схемы (UTF-8) помещают все биты продолжения в первый байт (таким образом, в первом байте есть только ограниченное пространство для битов данных) и 8 бит для остальных в последовательности.

person Marc Gravell    schedule 17.04.2010
comment
Хорошая точка зрения. Но по использованию я вижу, что значение равно 7 (в массиве есть еще семь секций координат. - person Vaccano; 18.04.2010

Если вы просто хотите поместить эти два байта рядом друг с другом в двоичном формате и посмотреть, что это за большое число в десятичном формате, вам необходимо использовать этот код:

if (BitConverter.IsLittleEndian)
{
    byte[] tempByteArray = new byte[2] { Item[5], Item[4] };
    ushort num = BitConverter.ToUInt16(tempByteArray, 0);
}
else
{
    ushort num = BitConverter.ToUInt16(Item, 4);
}

Если вы используете short num = BitConverter.ToInt16(Item, 4);, как показано в принятом ответе, вы предполагаете, что первый бит из этих двух байтов является битом знака (1 = отрицательный и 0 = положительный). Этот ответ также предполагает, что вы используете систему с прямым порядком байтов. См. this для получения дополнительной информации о знаковом бите.

person David Klempfner    schedule 04.03.2015

Если эти байты являются «частями» целого числа, это работает так. Но имейте в виду, что порядок байтов зависит от платформы и также зависит от длины целого числа (16 бит = 2 байта, 32 бит = 4 байта, ...)

person Danvil    schedule 17.04.2010

Если этот элемент [5] является MSB

  1. ushort result = BitConverter.ToUInt16 (новый байт [2] {элемент [5], элемент [4]}, 0);

  2. int result = 256 * Item [5] + Item [4];

person Amir Touitou    schedule 14.12.2017