Search code examples
cfloating-pointformatieee-754

C - how to store IEEE 754 double and single precision


I have to work with IEEE 745 double and single precision numbers. I have no idea, how to work with them correctly.

I've got a buffer of binary data and I want to get the numbers like

uint8_t bufer[] = {................};
//data I want are at 8th position, (IEEE745_t is my imaginary format)
IEEE745double_t first8bytes = *(IEEE745double_t*)(buffer + 8);
IEEE745single_t next4bytes = *(IEEE745single_t*)(buffer + 16);

What do I put instead of IEE745double_t and IEEE745single_t ? Is it possible to do it with double and float? And if so, how can I guarantee, that they will be 8 and 4 bytes long on every platform?


Solution

  • First of all, you cannot do the pointer cast hack. There is absolutely no guarantee that your byte buffer is correctly aligned. This results in undefined behaviour. Use memcpy instead:

    memcpy(&first8bytes, &buffer[8], 8); 
    memcpy(&next4bytes, &buffer[16], 4); 
    

    What do I put instead of IEE745double_t and IEEE745single_t? Is it possible to do it with double and float?

    Yes, it's possible, if:

    • double is 8 bytes, float is 4 bytes and both use IEEE754 presentation.
    • Data on buffer uses same byte order as your host. If not, you need to copy to temporary unsigned integer type first, where you fix the endianness.

    And if so, how can I guarantee, that they will be 8 and 4 bytes long on every platform?

    Use static assertion to detect when it's not. For example:

    static_assert(sizeof(float) == 4, "invalid float size");