Преобразование HEX->DEC без изменения системы счисления
есть данные в hex файле примерно такого вида: byte[] data = {0x11 0x48 0x42 0x50 0x00 0x00} здесь записано значение 1148.42500000 в dec. Не знаю что за сумрачный гений такое придумал... два первых байта всегда целая часть, 4 следующих байта - дробная. Нужно как-то вытаскивать float из этого массива байт. Придумал такое решение:
float.Parse(bytes[0].ToString("X2") + bytes[1].ToString("X2") + "." + bytes[2].ToString("X2") + bytes[3].ToString("X2"), System.Globalization.CultureInfo.InvariantCulture)
существует ли более элегантное решение для этого?
Ответы (3 шт):
byte[] bytes = { 0x11, 0x48, 0x42, 0x50, 0x00, 0x00 };
float result = float.Parse(
string.Join("", bytes.Select(b => b.ToString("X2"))).Insert(4, ","));
Console.WriteLine(result); //=> 1148,425
Существует менее затратное решение для конвертирования во float :
byte[] data = { 0x11, 0x48, 0x42, 0x50, 0x00, 0x00 };
float result = 0;
foreach (byte bt in data)
{
result *= 100;
result += (float)(10*(bt >> 4) + (bt & 0xf));
}
result /= 100000000;
Console.WriteLine(result); //1148.425
Старшая часть легко отделяется от младшей. Наверно разработчик очень любил двочно-десятичное кодирование. https://ru.wikipedia.org/wiki/%D0%94%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D0%BE-%D0%B4%D0%B5%D1%81%D1%8F%D1%82%D0%B8%D1%87%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4 Старшая часть от младшей можно отделить сдвигом на 4 или делением на 16, а младшую - остаток от деления на 16 либо "and 15".
Я бы расшифровал бы так (для любителей линейного выражения):
byte[] d = {0x11, 0x48, 0x42 ,0x50, 0x00, 0x00};
double result =
(d[0]>>4)*1000 + (d[0]&15)*100 +
(d[1]>>4)*10 + (d[1]&15)*1 +
(d[2]>>4)*.1 + (d[2]&15)*.01+
(d[3]>>4)*.001 + (d[3]&15)*.0001+
(d[4]>>4)*.00001 + (d[4]&15)*.000001;
Console.WriteLine(result);
Если громоздко - можно обвернуть в цикл (для любителей циклов).
byte[] d = {0x11, 0x48, 0x42 ,0x50, 0x00, 0x00};
double multi = 100;
double result = 0;
for (int i = 0; i<5; i++ ) {
result += (d[i]>>4)*10*multi + (d[i]&15)*multi;
multi =multi/100.0;
}