简体   繁体   中英

Convert double value from little endian to Big endian

I am converting from little endian to big endian and back to little checking
is it right or wrong please help me

#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>


double dx = 122992001003000;

//A method little to big endian

double bEndian(double d) {

    int *p0 = (int *) &d;
    int *p1 = p0 + 1;

    printf("1: %x %x\n", *p0, *p1);

    int tmp = *p1;
    *p1 = htonl(*p0);
    *p0 = htonl(tmp);

    printf("2: %x %x\n", *p0, *p1);

    return *(double *)p0;
}

//A method  big to little endian

double lEndian(double d) {
    int *p0 = (int *) &d;
    int *p1 = p0 + 1;

    printf("3: %x %x\n", *p0, *p1);

    int tmp = *p1;
    *p1 = ntohl(*p0);
    *p0 = ntohl(tmp);

    printf("4: %x %x\n", *p0, *p1);

    return *(double *)p0;
}

int main (int argc, char *argv[]) 
{       
    double d1 = bEndian(dx);

    double d2 = lEndian(d1);

    printf("5: %.0f\n", d2);

    if ((*(double*) &d2) == dx)
      printf("6: %.0lf\n", *(double*) &d2);
    else
      printf("7:%d\n", d2);

    return 0;
}

some time it give me result 122992001003129 why? also using ntohl or htonl have no difference ?? is it only for convention ie network to host and host to network

Here is a function that will change the endianness.

#include <algorithm>
#include <cstdio>

template <class T>
T change_endian(T in)
{
    char* const p = reinterpret_cast<char*>(&in);
    for (size_t i = 0; i < sizeof(T) / 2; ++i)
        std::swap(p[i], p[sizeof(T) - i - 1]);
    return in;
}

int main()
{
    double d = 122992001003000;
    printf("%f\n", d);
    d = change_endian(d);
    printf("%f\n", d);
    d = change_endian(d);
    printf("%f\n", d);
}

Output:

122992001003000.000000
0.000000
122992001003000.000000

Easy:

#include <endian.h>
#include <stdint.h>

double  src_num = YOUR_VALUE;
int64_t tmp_num = htobe64(le64toh(*(int64_t*)&src_num));
double  dst_num = *(double*)&tmp_num;

However, there're certain quirks: https://en.wikipedia.org/wiki/Endianness#Floating_point

typedef union
{
    double d;
    unsigned char s[8];
} Union_t;

// reverse little to big endian or vice versa as per requirement
double reverse_endian(double in)
{
    int i, j;
    unsigned char t;
    Union_t val;

    val.d = in;
    // swap MSB with LSB etc.
    for(i=0, j=7; i < j; i++, j--)
    {
        t = val.s[i];
        val.s[i] = val.s[j];
        val.s[j] = t;
    }
    return val.d;
}

Simple reversal of four bytes should work

double ReverseDouble( const double indouble )
{
   double retVal;
   char *doubleToConvert = ( char* ) & indouble;
   char *returndouble = ( char* ) & retVal;

   // swap the bytes into a temporary buffer
   returndouble[0] = doubleToConvert[3];
   returndouble[1] = doubleToConvert[2];
   returndouble[2] = doubleToConvert[1];
   returndouble[3] = doubleToConvert[0];

   return retVal;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM