San*_*Kim 0 c++ floating-point bitset type-punning
我知道。我知道。这个问题之前已经回答过,但我有一个稍微不同且更具体的问题。
正如标题所示,我的目标是浮动序列cout。32 bits
前面的问题提供的解决方案是使用联合。
union ufloat{
float f;
uint32_t u;
};
Run Code Online (Sandbox Code Playgroud)
这一切都很好。我已经成功地打印了浮点数的位。
union ufloat uf;
uf.f = numeric_limits<float>::max();
cout << bitset<32>(uf.f) << "\n"; // This give me 0x00000000, which is wrong.
cout << bitset<32>(uf.u) << "\n"; // This give me the correct bit sequence.
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么 dobitset<32>(uf.f)不起作用,但 bitset<32>(uf.u) 起作用?
这个问题的绿色勾号答案 获取了 C 中浮点数的位表示说了一些关于“类型双关”的内容,我认为它与此有关。但我不确定具体如何。
有人可以澄清一下吗?谢谢
您正在调用的构造函数std::bitset是:
constexpr bitset( unsigned long long val ) noexcept;
当您这样做时bitset<32>(uf.f),您正在将 a 转换float为一个unsigned long long值。对于numeric_limits<float>::max(),这是未定义的行为,因为它超出了目标类型的范围,并且在您的情况下它恰好产生零。
当您这样做时bitset<32>(uf.u),您再次依赖于未定义的行为,在这种情况下,它恰好执行您想要的操作:将uint32_t包含 a 的位的a 转换float为unsigned long long值。
在 C++ 中,您应该使用 memcpy:
uint32_t u;
std::memcpy(&u, &uf.f, sizeof(u));
std::cout << std::bitset<32>(u) << "\n";
Run Code Online (Sandbox Code Playgroud)