Конвертировать 2 байта в число - PullRequest
10 голосов
/ 18 апреля 2010

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

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

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

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

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

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

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

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

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

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

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

Ответы [ 6 ]

21 голосов
/ 18 апреля 2010

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

// assumes byte[] Item = someObject.GetBytes():
short num = BitConverter.ToInt16(Item, 4); // makes a short 
    // out of Item[4] and Item[5]
11 голосов
/ 18 апреля 2010

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

value = 256 * high + low;

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

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

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

7 голосов
/ 18 апреля 2010

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

Для 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 битов для остальных в последовательности.

2 голосов
/ 04 марта 2015

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

            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 для получения дополнительной информации о знаковом бите.

0 голосов
/ 14 декабря 2017

В случае, если позиция [5] является MSB

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

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

0 голосов
/ 18 апреля 2010

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

...