Search code examples
c++castingbit-manipulation

Encode a std::uint64_t into vector of floats


I have to do some dirty trickery and pass a std::uint64_t around an application. Unfortunately I am limited to using a std::vector<float> for that.

To my understanding float is 32-bit on most platforms, so it should be possible to split the 64-bit std::uint64_t into two 32-bit ints, represent those as float put them in the vector and reverse the process at the other end.

How can I do this?


Solution

  • Quick and dirty, but standard compliant if I'm not mistaken:

    #include <cassert>
    // using assert
    #include <cstdint>
    // using std::uint64_t
    #include <cstring>
    // using std::memcpy
    #include <vector>
    
    std::vector<float> pack(std::uint64_t value)
    {
        static_assert(sizeof(value) >= sizeof(float));
        static_assert(sizeof(value) % sizeof(float) == 0);
        std::vector<float> rtrn(sizeof(value) / sizeof(float));
        std::memcpy(rtrn.data(), &value, sizeof(value));
        return rtrn;
    }
    std::uint64_t unpack(const std::vector<float>& packed)
    {
        std::uint64_t rtrn;
        assert(packed.size() == sizeof(rtrn) / sizeof(float));
        std::memcpy(&rtrn, packed.data(), sizeof(rtrn));
        return rtrn;
    }