Ms. Molly Stewart-Gallus
Ms. Molly Stewart-Gallus

Reputation: 1168

How can I convert 4 bytes storing an IEEE 754 floating point number to a float value in C?

My program reads into 4 bytes an IEEE 754 floating point number from a file. I need to portable convert those bytes to my C compilers float type. In other words I need a function with the prototype float IEEE_754_to_float(uint8_t raw_value[4]) for my C program.

Upvotes: 3

Views: 8533

Answers (3)

Ms. Molly Stewart-Gallus
Ms. Molly Stewart-Gallus

Reputation: 1168

Here is a solution that portable transforms an IEEE_754 number to one's C compiler's float value. This code works but the loop to get the value of the fraction is is ugly, and can be done better. As well, this code does not handle special cases like infinity, and not a number.

float IEEE_754_to_float(const uint8_t raw[4]) {
        int sign = (raw[0] >> 7) ? -1 : 1;

        int8_t exponent = (raw[0] << 1) + (raw[1] >> 7) - 126;

        uint32_t fraction_bits = ((raw[1] & 0x7F) << 16) + (raw[2] << 8) + raw[3];

        float fraction = 0.5f;
        for (uint8_t ii = 0; ii < 24; ++ii)
                fraction += ldexpf((fraction_bits >> (23 - ii)) & 1, -(ii + 1));

        float significand = sign * fraction;

        return ldexpf(significand, exponent);
}

Upvotes: 1

user529758
user529758

Reputation:

If your implementation can guarantee correct endianness:

float raw2ieee(uint8_t *raw)
{
    // either
    union {
        uint8_t bytes[4];
        float fp;
    } un;
    memcpy(un.bytes, raw, 4);
    return un.fp;

    // or, as seen in the fast inverse square root:
    return *(float *)raw;
}

Upvotes: 5

Kerrek SB
Kerrek SB

Reputation: 476930

If the endianness is the same, then like so:

float f;
memcpy(&f, raw_value, sizeof f);
return f;

If not, say:

float f;
char * p = (char *)&f;

And now populate the bytes p[0]... manually as needed.

Upvotes: 2

Related Questions