使用 union
类型方式将浮点数的二进制形式保存到 uint32_t
变量中时,需要考虑大小端的影响。
在大端系统中,浮点数的最高字节位于内存的低地址处,而在小端系统中,浮点数的最低字节位于内存的低地址处。因此,当使用 union
类型方式时,如果浮点数和 uint32_t
共用同一段内存空间,需要根据实际的系统大小端模式来确保正确的读取和保存。
以下是一个示例代码,考虑了大小端的影响:
#include <stdio.h> #include <stdint.h> union FloatToUint32 { float f; uint32_t u; uint8_t bytes[4]; }; void flt_to_int(float src, uint32_t *dst) { union FloatToUint32 converter; converter.u = 1; if(converter.bytes[0] == 0) { // 如果是小端系统,则将低地址处的 uint32_t 赋值给目标变量 converter.f = src; *dst = converter.u; } else { // 如果是大端系统,则将高地址处的 uint32_t 赋值给目标变量 converter.f = src; *dst = ((converter.u&0x000000FF)<< 24)|((converter.u&0xFF000000)>> 24)|((converter.u&0x00FF0000)>> 8)|((converter.u&0x0000FF00)<< 8); } } int main() { float temp = 10000.0f; uint32_t val; flt_to_int(temp, &val); printf("0x%08x\n", val); return 0; }
示例代码违反misra-c2012-19.2建议规则。使用强转或是memcpy又会违反别的规则 :---)
以下示例可以符合MISRA。
#include <stdint.h> #include <string.h> // 在主函数之前包含 string.h 头文件 uint32_t flt_to_int(float src); uint32_t flt_to_int(float src) { uint32_t dest = 0; ((unsigned char*)(&dest))[0] = ((unsigned char*)(&src))[0]; ((unsigned char*)(&dest))[1] = ((unsigned char*)(&src))[1]; ((unsigned char*)(&dest))[2] = ((unsigned char*)(&src))[2]; ((unsigned char*)(&dest))[3] = ((unsigned char*)(&src))[3]; return dest; } int main() { float temp = 10000.0f; uint32_t val = flt_to_int(temp); printf("%08x", val); return 0; }