将三个字节组合成一个 24 位(实际上是 32 位)值是 C 位运算符的简单应用。
这是一个冗长的“速记”形式:
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 数组)的类型通常非常重要 @ 987654332@。如果不是——例如,如果它是在大多数机器上签名的普通char——你通常最终会遇到令人衰弱的符号扩展问题。例如,您的值 140 是十六进制数 0x8c,如您所知,但解释为 有符号 8 位数字,即 -116。当它与其他整数一起参与表达式时,它通常会被符号扩展为0xff8c 或0xffffff8c,这当然不是你想要的。 (您可以使用额外的 & 0xff 掩码解决此问题,正如 SteveB 的回答中所建议的那样,但这很麻烦。使用 unsigned char 更简单。)