Преобразовать 2 байта в число
у меня есть элемент управления, в котором есть массив байтов.
время от времени есть два байта, которые говорят мне некоторую информацию о количестве будущих элементов в массиве.
Так, в качестве примера я мог бы:
... ... Item [4] = 7 Item [5] = 0 ... ...
значение этого явно 7.
но как насчет этого?
... ... Item [4] = 0 Item [5] = 7 ... ...
любая идея о том, что это приравнивается к (как нормальный int)?
Я пошел в binary и подумал, что это может быть 11100000000, который равен 1792. но я не знаю, действительно ли это так работает (т. е. использует ли он все 8 элементов для байта).
есть ли способ узнать это без тестирования?
Примечание: я использую C# 3.0 и visual studio 2008
7 ответов
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 = положительный). Этот ответ также предполагает, что вы используете большой системы с обратным порядком байтов. См.этой для получения дополнительной информации о знаке бит.
Используйте BitConveter.ToInt32 im не 100% уверен, что даст вам правильный результат, но вы можете попробовать
Если эти байты являются "частями" целого числа она работает. Но будьте осторожны, что порядок байтов специфичен для платформы и что он также зависит от длины целого числа (16 бит=2 байта, 32 бит=4bytes, ...)
в случае, если этот пункт[5] является MSB
результат ushort = BitConverter.ToUInt16 (новый байт[2] { Item[5], Item[4] }, 0);
int result = 256 * Item[5] + Item[4];