将uint32_t铸造到c/c 中浮动
bitwise casting uint32_t to float in C/C++
我正在从网络中接收一个缓冲区,该网络被转换为32位单词的数组。我有一个单词,该单词被我的接口文档定义为IEEE-754浮动。我需要从缓冲区中提取这个单词。在不调用转换的情况下,很难从一种类型到另一种类型。这些位已经遵守IEEE-754浮点标准,我不想重新安排任何位。
我的第一次尝试是将uint32_t
的地址投放到void*
,然后将void*
转换为float*
,然后将其解释为float
:
float ieee_float(uint32_t f)
{
return *((float*)((void*)(&f)));
}
错误:删除类型 - 划分指针将破坏严格确定的规则[-werror = strict-oliasing]
我的第二次尝试就是这样:
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-oliasing]
我的下一个想法是"拧"它。为什么我无论如何都要处理指针?"刚刚尝试:
float ieee_float(uint32_t f)
{
return reinterpret_cast<float>(f);
}
错误:从类型'uint32_t {aka unsigned int}'type" float'
(
有没有触发警告/错误的方法进行转换的方法?我正在使用-Wall -Werror
使用G 编译。我宁愿不触摸编译器设置。
i标记了C,因为C-解决方案是可以接受的。
在C 20中,您可以使用std::bit_cast
:
float ieee_float(uint32_t f)
{
return std::bit_cast<float>(f);
}
在C 17和之前,正确的方式™是:
float ieee_float(uint32_t f)
{
static_assert(sizeof(float) == sizeof f, "`float` has a weird size.");
float ret;
std::memcpy(&ret, &f, sizeof(float));
return ret;
}
-O1
及更高版本的GCC和Clang为此代码生成相同的组件和幼稚的reinterpret_cast<float &>(f)
(但后者是未定义的行为,在某些情况下可能不起作用(。
没有C/C 语言。它们是具有不同规则的不同语言。C中的有效方法是使用联合,但在C 中不允许使用联合。参见
- 工会和类型 - 束缚
- 通过C99中未指定的工会进行了键入,并且是否在C11中指定?
在较旧的C 标准中,您必须使用std::memcpy
。即使是reinterpret_cast
,类型的双关语都会调用未定义的行为,因此不允许。在C 20中,完全为此目的创建了一种称为std::bit_cast
的新型演员类型
float ieee_float(uint32_t f)
{
return std::bit_cast<float>(f);
}
另请参见:
- 如何将浮子插入flot到int,反之亦然是什么?
- 在C 中进行键入的现代,正确的方法是什么?
您有几个选项,如下所示:
- 使用
union
解决方案:由于C11明确允许(如其他答案中所述(。 - 而不是使用32位单词的数组,而是使用8位单词(UINT8_T(的数组,因为
char
类型可以与任何类型的类型相称。
- memcpy 是将浮子打包到 uint32 中的标准方法吗?
- 警告C4018,包含int和UINT32,但不包含int和UCHAR
- 为什么 UInt64 变量不能包含大于 UInt32::Max 的值?
- C++:从 "const variable*" 转换为"uint32"会失去精度
- 从指针到 uint32 的类型转换
- 为什么当我使用双精度时,Qt<->Matlab 正确写入和读取我的字节,但存储 uint32 的字节不正确?
- uint32, int16, uint8 .为什么这些常用的数据类型没有进入标准
- 将字符 * 转换为 uint16 和 uint32
- 如何将UINT8*施放到UINT32
- 从4个浮子创建UINT32
- 访问联合的成员变量:为 uint64 声明,但想要在 uint32 中的内容。C++
- 读取结构 -- uint32 不命名类型
- 手臂霓虹灯转置 4x4 uint32
- 错误:智能感知:标识符"uint32"未定义?
- 在uint32中存储自Epoch以来的毫秒是否安全
- 警告缩小转换范围(uint32 到 uint8)
- 使用 python 编译引脚工具的错误包括,得到错误 C2872:'UINT32':不明确的符号
- 在 c++ 中将两个 uint32 组合到 ulong64
- 将 UINT32 颜色格式从 AaBbGgRr 转换为 AaRrGgBb
- 如何将位集变量的内容存储到 c 中的 uint32