How do I convert between big-endian and little-endian values in C++?

前端 未结 30 2571
难免孤独
难免孤独 2020-11-21 23:18

How do I convert between big-endian and little-endian values in C++?

EDIT: For clarity, I have to translate binary data (double-precision floating point values and 3

30条回答
  •  悲哀的现实
    2020-11-22 00:00

    Here's how to read a double stored in IEEE 754 64 bit format, even if your host computer uses a different system.

    /*
    * read a double from a stream in ieee754 format regardless of host
    *  encoding.
    *  fp - the stream
    *  bigendian - set to if big bytes first, clear for little bytes
    *              first
    *
    */
    double freadieee754(FILE *fp, int bigendian)
    {
        unsigned char buff[8];
        int i;
        double fnorm = 0.0;
        unsigned char temp;
        int sign;
        int exponent;
        double bitval;
        int maski, mask;
        int expbits = 11;
        int significandbits = 52;
        int shift;
        double answer;
    
        /* read the data */
        for (i = 0; i < 8; i++)
            buff[i] = fgetc(fp);
        /* just reverse if not big-endian*/
        if (!bigendian)
        {
            for (i = 0; i < 4; i++)
            {
                temp = buff[i];
                buff[i] = buff[8 - i - 1];
                buff[8 - i - 1] = temp;
            }
        }
        sign = buff[0] & 0x80 ? -1 : 1;
        /* exponet in raw format*/
        exponent = ((buff[0] & 0x7F) << 4) | ((buff[1] & 0xF0) >> 4);
    
        /* read inthe mantissa. Top bit is 0.5, the successive bits half*/
        bitval = 0.5;
        maski = 1;
        mask = 0x08;
        for (i = 0; i < significandbits; i++)
        {
            if (buff[maski] & mask)
                fnorm += bitval;
    
            bitval /= 2.0;
            mask >>= 1;
            if (mask == 0)
            {
                mask = 0x80;
                maski++;
            }
        }
        /* handle zero specially */
        if (exponent == 0 && fnorm == 0)
            return 0.0;
    
        shift = exponent - ((1 << (expbits - 1)) - 1); /* exponent = shift + bias */
        /* nans have exp 1024 and non-zero mantissa */
        if (shift == 1024 && fnorm != 0)
            return sqrt(-1.0);
        /*infinity*/
        if (shift == 1024 && fnorm == 0)
        {
    
    #ifdef INFINITY
            return sign == 1 ? INFINITY : -INFINITY;
    #endif
            return  (sign * 1.0) / 0.0;
        }
        if (shift > -1023)
        {
            answer = ldexp(fnorm + 1.0, shift);
            return answer * sign;
        }
        else
        {
            /* denormalised numbers */
            if (fnorm == 0.0)
                return 0.0;
            shift = -1022;
            while (fnorm < 1.0)
            {
                fnorm *= 2;
                shift--;
            }
            answer = ldexp(fnorm, shift);
            return answer * sign;
        }
    }
    

    For the rest of the suite of functions, including the write and the integer routines see my github project

    https://github.com/MalcolmMcLean/ieee754

提交回复
热议问题