Search code examples
c++unionsrawbytestring

How to read floating point value from raw bytes in memory?


I am trying to read a floating point value from a raw bytes array. I have a pointer to the raw bytes array and I would like to read the floating point value associated with the raw bytes. I am using a union data structure to read the floating point value, however I am unable to read the correct value.

// Floating point value: 0x3F800000 (floating point value 1.0)
char * c = "\u003F\u0080\u0000\u0000";
union char4_or_float {
    char element[4];
    float val;
} cf;
cf.element[0] = c[0];
cf.element[1] = c[1];
cf.element[2] = c[2];
cf.element[3] = c[3];
printf("%f", cf.val);

Expected result: 1.0, returned output: 0.0

I want to know if this code is correct. If not, could you please tell how to fix it? Also, if there are scenarios where it would not work, can you please mention them?

Thank you.


Solution

  • You have two problems:

    1. The use of unicode characters doesn't necessarily end up with the expected bytes in your string, try const char * c = "\x3F\x80\x00\x00"; instead
    2. You're presumably running on a little endian machine, your bytes are big endian so you need to swap when you do your copy:
    cf.element[0] = c[3];
    cf.element[1] = c[2];
    cf.element[2] = c[1];
    cf.element[3] = c[0];
    

    All of the above relies on undefined behaviour though, a memcpy would be much simpler and legal:

    #include <cstdio>
    #include <cstring>
    
    int main()
    {
        const char * c = "\x00\x00\x80\x3f";
        float f;
        std::memcpy(&f, c, sizeof(f));
        printf("%f", f);
    }