使用 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; }