Ответ 1
BitConverter
может легко преобразовать два байта в двухбайтовом целочисленном значении:
// assumes byte[] Item = someObject.GetBytes():
short num = BitConverter.ToInt16(Item, 4); // makes a short
// out of Item[4] and Item[5]
У меня есть элемент управления, в котором есть массив байтов.
Время от времени есть два байта, которые сообщают мне некоторую информацию о количестве будущих элементов в массиве.
Итак, в качестве примера я мог бы:
... ... Item [4] = 7 Item [5] = 0 ... ...
Значение этого явно 7.
Но как насчет этого?
... ... Item [4] = 0 Item [5] = 7 ... ...
Любая идея о том, что это означает (как обычный int)?
Я пошел в двоичный файл и думал, что это может быть 11100000000, что равно 1792 года. Но я не знаю, так ли это работает (т.е. использует ли он все 8 элементов для байта).
Есть ли способ узнать это без тестирования?
Примечание. Я использую С# 3.0 и visual studio 2008
BitConverter
может легко преобразовать два байта в двухбайтовом целочисленном значении:
// assumes byte[] Item = someObject.GetBytes():
short num = BitConverter.ToInt16(Item, 4); // makes a short
// out of Item[4] and Item[5]
Двухбайтовое число имеет низкий и высокий байт. Старший байт стоит 256 раз больше, чем младший байт:
value = 256 * high + low;
Итак, для high = 0 и low = 7 значение равно 7. Но для high = 7 и low = 0 значение становится 1792.
Это, конечно, предполагает, что число является простым 16-битным целым числом. Если это будет чем-то интересным, то этого недостаточно. Затем вам нужно узнать больше о том, как кодируется число, чтобы декодировать его.
Порядок появления верхнего и нижнего байтов определяется endianness потока байтов. В big-endian вы увидите высокий уровень до низкого (при более низком адресе), в little-endian это наоборот.
Вы говорите "это значение явно 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 бит для остальных в последовательности.
Если вы просто хотите поместить эти два байта рядом друг с другом в двоичном формате и посмотреть, что это большое число в десятичном виде, вам нужно использовать этот код:
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 = положительный). Этот ответ также предполагает, что вы используете систему с прямым порядком байтов. Смотрите это для получения дополнительной информации о знаке бит.
Если эти байты являются "частями" целого числа, он работает так. Но будьте осторожны, что порядок байтов является специфичным для платформы и что он также зависит от длины целого (16 бит = 2 байта, 32 бит = 4 байта,...)
Использовать BitConveter.ToInt32 im не на 100% уверен, что это даст вам правильный результат, но вы можете попробовать
Если элемент [5] является MSB
ushort result = BitConverter.ToUInt16 (новый байт [2] {Item [5], Item [4]}, 0);
int result = 256 * Item [5] + Item [4];