Home > Net >  Type punning in a const / static initializer (building a float constant from bits)
Type punning in a const / static initializer (building a float constant from bits)

Time:05-17

Some languages (like Rust, Zig, GLSL, HLSL) have built-in methods to build a floating type from bits supplied as an unsigned integer. However C and C do not have standard functions for that.

With C99 we can use anonymous unions with member initialization to implement a type punning macro to the same effect:

#define FLOAT_FROM_BITS(U,F,b) (((union{U u; F f;}){.u=(b)}).f)
#define FLOAT32_FROM_BITS(i) FPOW2(uint32_t, float,  i)
#define FLOAT64_FROM_BITS(i) FPOW2(uint64_t, double, i)

which can then subsequently be used to initialize const / static with. What would be the most elegant way to do this in C , so that it can also be used for static initialization?

CodePudding user response:

If you can use C 20 or above, then use std::bit_cast like

auto myvar = std::bit_cast<type_to_cast_to>(value_to_cast);

If you want to support older versions, you can do this same thing using std::memcpy to copy the bytes from one type to another. That would give you a function like

template <class To, class From>
To bit_cast(const From& src)
{
    To dst;
    std::memcpy(&dst, &src, sizeof(To));
    return dst;
}

CodePudding user response:

An elegant way is to use std::bit_cast:

std::uint64_t i = example_value();
auto d = std::bit_cast<double>(i);
  • Related