host to network double?
Asked Answered
U

3

5

I'd like to send some double precision floating point numbers over the network. (standard C, standard sockets) There is no htond or ntohd to convert the data to and from network byte order. What should I do? I have a couple solutions in my head but I'd like to know what the common practice is.

(I'd also like to know what is the common practice for sending 64bit ints, like gint64 values used by gstreamer)

edit: This is one solution I thought of. I presume it works for any size integers, but is it correct for doubles?

void swap_if_necessary (void* buff, int buff_len) 
{
    uint32_t foo = 1;
    if ( htonl(foo) != foo ) 
    {
        char* to_swap = (char*)buff;

        int i;
        for (i = 0; i < buff_len/2; i++)
        {
            char  swap_buff = to_swap[i];
            to_swap[i] = to_swap[buff_len -1 -i];  
            to_swap[buff_len -1 -i] = swap_buff;
        }  
    }
}
Unzip answered 21/5, 2011 at 20:27 Comment(4)
This section on Wikipedia explains the situation well.Esophagitis
Wouldn't you just send the 64-bit integer big endian like all other integers? How would that be different than other integers?Baronet
the problem is should I convert it to big endian myself, or is there some library that does that for me. The standard bsd sockets only have functions for 32 and 16 bit integers.Unzip
GCC provides __builtin_bswap64() - see gcc.gnu.org/onlinedocs/gcc/Other-Builtins.htmlDenicedenie
C
5

What Andre is saying is that binary floating point numbers are not trustworthy across networks because of differences between different computer architectures. Differences that go beyond byte order (big/little endian). Thus things like converting to strings or use of libraries such as XDR, is really necessary if there is any chance your data is going to be processed by different computer architectures.

The simple formats of integers and characters can slip through with just endian adjustments but floating point gets more complex.

Ceiba answered 21/5, 2011 at 21:38 Comment(1)
I think I'll do my own byte swap, the one I added in my question edit, but on 64bit ints instead of doubles. To be honest 64bit ints are enough for me. I want to send some time-related information I retrieve from gstreamer. It stores time intervals as number of milliseconds in 64 bit integers. I was just converting them to double for my own "satisfaction" because I'm used to NSTimeinterval, a time interval stored as the number of seconds (double floating point), used throughout Apple(iOS and OSX) C and ObjectiveC frameworks.Unzip
B
10

Convert it to an agreed string format and send that. Not sure if it's common practice or even decent, but it worked for me (it is true I did not care about performance at that point since I wasn't sending very many values).

Bullate answered 21/5, 2011 at 20:32 Comment(2)
It is common practice actually. There are simply too many variations on floating point formats. Converting from or to IEEE would be as expensive as using strtod. If you want to send a lot of data and want cheap conversion (sound, positions in a real time 3D game,...), consider sending fixed point numbers.Prince
I have used sprintf(...,"%.*e", DBL_DECIMAL_DIG -1, x) to be sufficient to uniquely convert double, (except NaN with a payload). sprintf(...,"%a", x) is good too.Tavarez
C
5

What Andre is saying is that binary floating point numbers are not trustworthy across networks because of differences between different computer architectures. Differences that go beyond byte order (big/little endian). Thus things like converting to strings or use of libraries such as XDR, is really necessary if there is any chance your data is going to be processed by different computer architectures.

The simple formats of integers and characters can slip through with just endian adjustments but floating point gets more complex.

Ceiba answered 21/5, 2011 at 21:38 Comment(1)
I think I'll do my own byte swap, the one I added in my question edit, but on 64bit ints instead of doubles. To be honest 64bit ints are enough for me. I want to send some time-related information I retrieve from gstreamer. It stores time intervals as number of milliseconds in 64 bit integers. I was just converting them to double for my own "satisfaction" because I'm used to NSTimeinterval, a time interval stored as the number of seconds (double floating point), used throughout Apple(iOS and OSX) C and ObjectiveC frameworks.Unzip
B
4

You might want to look at XDR which was first defined in rfc1014. Obviously, you want to find a library which implements XDR for your platform.

Bunkhouse answered 21/5, 2011 at 20:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.