我从网络接收到一个缓冲区,该缓冲区已转换为32位字的数组。我的接口文档将其中一个字定义为IEEE-754浮点数。我需要从缓冲区中提取这个字。但是,在不进行转换的情况下从一种类型强制转换为另一种类型很困难。这些位已经符合IEEE-754浮点数标准,我不想重新排列任何位。我的第一次尝试是将uint32_t的地址强制转换为void*,然后将void*转换为float*,最后作为float解除引用:
float ieee_float(uint32_t f)
{
return *((float*)((void*)(&f)));
}
错误: 解引用类型转换指针将违反严格别名规则 [-Werror=strict-aliasing]
我第二次尝试的代码如下:
float ieee_float(uint32_t f)
{
union int_float{
uint32_t i;
float f;
} tofloat;
tofloat.i = f;
return tofloat.f;
}
然而,街上流传着工会完全不安全的说法。从最近没有写入的联合成员中读取是未定义行为。
因此,我尝试了更多的C++方法:
float ieee_float(uint32_t f)
{
return *reinterpret_cast<float*>(&f);
}
错误:对强制类型转换的指针取消引用将违反严格别名规则[-Werror = strict-aliasing]
我的下一个想法是,“算了吧。我为什么要处理指针呢?”然后尝试:
float ieee_float(uint32_t f)
{
return reinterpret_cast<float>(f);
}
错误:从类型“uint32_t {aka unsigned int}”到类型“float”的转换无效
是否有一种方法可以在不触发警告/错误的情况下进行转换?我正在使用-Wall -Werror
编译g ++。我希望不要触及编译器设置。
我打上了C标签,因为接受C解决方案。
sizeof(float) != sizeof(std::uint32_t)
时应该发生什么? - Zeregesfloat ieee_float(uint32_t f) { void *p = &f; float fv = *(float*)p; return fv; }
but theunion
is cleanertypedef union { float f; uint32_t v; } fu;
thenfloat ieee_float(uint32_t f) { fu.v = f; return fu.f; }
- David C. Rankin