Преобразовать кодирование с плавающей точкой IEEE-754 в значение с плавающей точкой - PullRequest
0 голосов
/ 17 февраля 2019

Как можно преобразовать базовое 32-разрядное кодирование с плавающей запятой IEEE-754, например 0x466F9100, в представленное значение 15332,25?

1 Ответ

0 голосов
/ 17 февраля 2019
#include <inttypes.h>
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>


/*  Interpret a string containing a numeral for an integer value as an encoding
    of an IEEE-754 basic 32-bit binary floating-point value.
*/
static float Interpret(const char *s)
{
    //  Interpret the string as an integer numeral.  Errors are not handled.
    uint32_t x = strtoumax(s, NULL, 16);

    //  Separate the sign (1 bit), exponent (8), and significand (23) fields.
    uint32_t sign        = x>>31;
    uint32_t exponent    = (x>>23) & 0xff;
    uint32_t significand = x & 0x7fffff;

    //  Interpret the sign field.
    float Sign = sign ? -1 : +1;

    //  Create an object to hold the magnitude (or NaN).
    float Magnitude;

    //  How we form the magnitude depends on the exponent field.
    switch (exponent)
    {
        //  If the exponent field is zero, the number is zero or subnormal.
        case 0:
        {
            //  In a zero or subnormal number, the significand starts with 0.
            float Significand = 0 + significand * 0x1p-23f;

            //  In a zero or subnormal number, the exponent has its minimum value.
            int Exponent = 1 - 127;

            //  Form the magnitude from the significand and exponent.
            Magnitude = ldexpf(Significand, Exponent);

            break;
        }

        //  If the exponent field is all ones, the datum is infinity or a NaN.
        case 0x7fffff:
        {
            /*  If the significand field is zero, the datum is infinity.
                Otherwise it is a NaN.  Note that different NaN payloads and
                types (quiet or signaling) are not supported here.  Standard C
                does not provide good support for these.
            */
            Magnitude = significand == 0 ? INFINITY : NAN;
            break;
        }

        //  Otherwise, the number is normal.
        default:
        {
            //  In a normal number, the significand starts with 1.
            float Significand = 1 + significand * 0x1p-23f;

            //  In a normal number, the exponent is biased by 127.
            int Exponent = (int) exponent - 127;

            //  Form the magnitude from the significand and exponent.
            Magnitude = ldexpf(Significand, Exponent);
        }
    }

    //  Combine the sign and magnitude and return the result.
    return copysignf(Magnitude, Sign);
}


int main(void)
{
    printf("%.99g\n", Interpret("0x466F9100"));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...