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.
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;
}
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.
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);
}
来源:https://stackoverflow.com/questions/12242187/how-can-i-convert-4-bytes-storing-an-ieee-754-floating-point-number-to-a-float-v