I know. I know. This question has been answered before, but I have a slightly different and a bit more specific question.
My goal is, as the title suggest, to cout the 32 bits sequence of a float.
And the solution provided in the previous questions is to use a union.
union ufloat{
float f;
uint32_t u;
};
This is all good and well. And I have managed to print the bits of a floating number.
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.
My question is why does bitset<32>(uf.f) doesn't work, but bitset<32>(uf.u) does?
The green-ticked anwser of this question Obtaining bit representation of a float in C says something about "type-punning", and I presume it's got something to do with that. But I am not sure how exactly.
Can someone please clearify? Thanks
The constructor of
std::bitsetyou are calling is:constexpr bitset( unsigned long long val ) noexcept;When you do
bitset<32>(uf.f), you are converting afloatto anunsigned long longvalue. Fornumeric_limits<float>::max(), that's undefined behavior because it's outside the range of the destination type, and in your case it happened to produce zero.When you do
bitset<32>(uf.u), you are again relying on undefined behavior, and in this case it happens to do what you want: convert auint32_tthat contains the bits of afloatto anunsigned long longvalue.In C++, what you should do instead is use memcpy: