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

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

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

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

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

Значение этого явно 7.

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

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

Любая идея о том, что это означает (как обычный int)?

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

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

Примечание. Я использую С# 3.0 и visual studio 2008

Ответ 1

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

// assumes byte[] Item = someObject.GetBytes():
short num = BitConverter.ToInt16(Item, 4); // makes a short 
    // out of Item[4] and Item[5]

Ответ 2

Двухбайтовое число имеет низкий и высокий байт. Старший байт стоит 256 раз больше, чем младший байт:

value = 256 * high + low;

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

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

Порядок появления верхнего и нижнего байтов определяется endianness потока байтов. В big-endian вы увидите высокий уровень до низкого (при более низком адресе), в little-endian это наоборот.

Ответ 3

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

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

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

и для big-endian:

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

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

Ответ 4

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

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 = положительный). Этот ответ также предполагает, что вы используете систему с прямым порядком байтов. Смотрите это для получения дополнительной информации о знаке бит.

Ответ 5

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

Ответ 6

Использовать BitConveter.ToInt32 im не на 100% уверен, что это даст вам правильный результат, но вы можете попробовать

Ответ 7

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

  • ushort result = BitConverter.ToUInt16 (новый байт [2] {Item [5], Item [4]}, 0);

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