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.
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
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;
}
回答2:
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.
回答3:
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);
}