Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
296 views
in Technique[技术] by (71.8m points)

c++ - How to manage endianess of double from network

I have a BIG problem with the answer to this question Swap bits in c++ for a double

Yet, this question is more or less what I search for: I receive a double from the network and I want to encoded it properly in my machine.


In the case I receive an int I perform this code using ntohl :

int * piData = reinterpret_cast<int*>((void*)pData);

//manage endianness of incomming network data 
unsigned long ulValue = ntohl(*piData);
int iValue = static_cast<int>(ulValue);

But in the case I receive an double, I don't know what to do.

The answer to the question suggest to do:

template <typename T>
void swap_endian(T& pX)
{
    char& raw = reinterpret_cast<char&>(pX);
    std::reverse(&raw, &raw + sizeof(T));
}

However , if I quote this site:

The ntohl() function converts the unsigned integer netlong from network byte order to host byte order. When the two byte orders are different, this means the endian-ness of the data will be changed. When the two byte orders are the same, the data will not be changed.

On the contrary @GManNickG's answer to the question always does the inversion with std::reverse .

Am I wrong considering that this answer is false ? ( in the extent of network management of endianess which the use of ntohl suggest though it was not precisely said in the title of the OP question).

In the end: Should I split my double into two parts of 4 bytes and apply the ntohl function on the two parts ? Are there more cannonical solutions ?

There's also this interesting question in C, host to network double?, but it limits to 32 bits values. And the answer says doubles should be converted to strings because of architecture differences... I'm also gonna work with audio samples, should I really consider converting all the samples to strings in my database ? ( the doubles come from a database that I query over the network)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

If your doubles are in IEEE 754 format that you should be relatively OK. Now you have to divide their 64 bits into two 32-bit halves and then transmit them in big-endian order (which is network order);

How about:

void send_double(double d) {
    long int i64 = *((reinterpret_cast<int *>)(&d)); /* Ugly, but works */
    int hiword = htonl(static_cast<int>(i64 >> 32));
    send(hiword);
    int loword = htonl(static_cast<int>(i64));
    send(loword);
}

double recv_double() {
    int hiword = ntohl(recv_int());
    int loword = ntohl(recv_int());
    long int i64 = (((static_cast<long int>) hiword) << 32) | loword;
    return *((reinterpret_cast<double *>(&i64));
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...