Объединение трех байтов в одно 24-битное (фактически 32-битное) значение является простым применением побитовых операторов Си.Вот это в подробном, "длинном" виде:
unsigned char data_buffer[] = { 24 , 17 , 140 };
unsigned long int data_value = 0;
data_value |= data_buffer[0];
data_value <<= 8;
data_value |= data_buffer[1];
data_value <<= 8;
data_value |= data_buffer[2];
Я бы, вероятно, написал это в более компактной форме:
unsigned long int data_value = 0;
data_value |= data_buffer[0];
data_value = (data_value << 8) | data_buffer[1];
data_value = (data_value << 8) | data_buffer[2];
Или вы можете сделать это в другом порядкетак сказать:
unsigned long int data_value = 0;
data_value |= (unsigned long)data_buffer[0] << 16;
data_value |= data_buffer[1] << 8;
data_value |= data_buffer[2];
(Здесь вам нужно дополнительное преобразование, однако, если вы используете 16-битный процессор, где обычный data_buffer[0] << 16
сдвинет все биты и потеряет их.)
Или вы можете сделать все это сразу:
unsigned long int data_value =
((unsigned long)data_buffer[0] << 16) |
(data_buffer[1] << 8) |
data_buffer[2];
В любом случае вы можете затем выполнить необходимое деление:
float float_value = (float)data_value / 0x7FFFFF;
(ВыВозможно, вы захотите использовать double
вместо float
. Или, в зависимости от ограничений встроенной среды, вы можете вообще не использовать прямую с плавающей точкой, как вы; вы не сказали.)
Когда я их распечатываю, я получаю запрошенные вами значения:
printf("data_value = %#lX, float_value = %f\n", data_value, float_value);
выход:
data_value = 0X18118C, float_value = 0.188036
Добавление: я забыл упомянуть, что для этих методовработают правильно, обычно действительно важно , чтобы ваши входные данные, т.е. массив data_buffer
в вашем примере, имели тип unsigned char
,Если это не так - например, если это просто char
, который подписан на большинстве машин - у вас обычно возникают изнурительные проблемы с расширением знака.Например, ваше значение 140 - это шестнадцатеричное число 0x8c
, как вы знаете, но оно интерпретируется как знаковое 8-битное число, это -116.И когда он участвует в выражении с другими целыми числами, он обычно расширяется до 0xff8c
или 0xffffff8c
, что, конечно, совсем не то, что вам нужно.(Вы можете обойти это с помощью дополнительных масок & 0xff
, как предложено в ответе SteveB, но это неудобство. Гораздо проще использовать unsigned char
.)