Floating point number to 32 and 64bit binary repre

2020-05-09 23:32发布

问题:

I need to get 64 bit binary representation (IEEE 754) of some floating point value (double value). I have this code for 32 bit binary representation of float:

union
{
    float input;   // assumes sizeof(float) == sizeof(int)
    int   output;
}   data;
data.input = value;
std::bitset<sizeof(float) * CHAR_BIT>   bits(data.output);

How union relates to convert in this situation? Why I should to use it? Is there some pretty way to do the same to get 64bit representation?

回答1:

How union relates to convert in this situation?

In C11, you are permitted to use unions to perform "type-punning", which is the essence of your conversion here: reinterpreting the bits associated with a float instead as a (signed, presumed 32-bit) integer.

Why I should to use it?

You should not use this. In C++, this is considered undefined behavior, and while many mainstream compilers will support union-based-type-punning out-of-the-box, they cannot be relied upon to always provide this behavior, especially as the C++ standard changes in the future.

Is there some pretty way to do the same to get 64bit representation?

If your compiler guarantees union-based-type-punning, then you need only replace this with the appropriate 64-bit integer:

static_assert(sizeof(double) == sizeof(uint64_t));
union {
    double input;
    uint64_t output;
} data;
data.input = value;
std::bitset<sizeof(double) * CHAR_BIT> bits(data.output);

If it doesn't, then there's no pretty way to do this, but there is a way to do it while guaranteeing defined behavior:

static_assert(sizeof(double) == sizeof(uint64_t));
uint64_t output;
double input = value;
memcpy(output, input, sizeof(double));
std::bitset<sizeof(double) * CHAR_BIT> bits(output);