Intereting Posts

Как я могу конвертировать 4 байта, сохраняя число с плавающей точкой IEEE 754, в значение float в C?

Моя программа считывает в 4 байта номер с плавающей запятой IEEE 754 из файла. Мне нужно, чтобы переносить эти байты в мои компиляторы C-типа с плавающей запятой. Другими словами, мне нужна функция с прототипом float IEEE_754_to_float(uint8_t raw_value[4]) для моей программы на C.

Если ваша реализация может гарантировать правильность утверждения:

 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; } 

Если консистенция одинакова, то вот так:

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

Если нет, скажите:

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

А теперь запишите байты p[0] … вручную по мере необходимости.

Вот решение, которое переносит преобразование числа IEEE_754 в значение плавающего C-компилятора. Этот код работает, но цикл для получения значения фракции является уродливым и может быть сделано лучше. Кроме того, этот код не обрабатывает особые случаи, такие как бесконечность, а не число.

 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); }