#include<stdio.h>
#include <string.h>

/** copy the bytes at data directly into a double. 
    and return that.
*/
double directValue(const char *data)
{
	double result;
	char *dest = (char *)&result;
	
	memcpy(dest, data, sizeof(double));
	
	return result;
}

/** copy the bytes at data into a double, reversing the
    byte order, and return that.
*/
double reverseValue(const char *data)
{
	double result;
	
	char *dest = (char *)&result;
	
	for(int i=0; i<sizeof(double); i++) 
	{
		dest[i] = data[sizeof(double)-i-1];
	}
	return result;
}

/** Adjust the byte order from network to host.
    On a big endian machine this is a NOP.
	There is no error handling 
*/
double ntohd(double src)
{
#	if		!defined(__FLOAT_WORD_ORDER__) \
		||	!defined(__ORDER_LITTLE_ENDIAN__)
#		error "oops: unknown byte order"
#	endif

#	if __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__
		return reverseValue((char *)&src);
#	else
		return src;
#	endif
}

int main() 
{
	// big endian, i.e. network byte order
	const char onedotsomethingbytes[]
				= {0x3F, 0xF3, 0xC0, 0xCA, 0x42, 0x83, 0xDE, 0x1B};

	double directDbl = directValue(onedotsomethingbytes);			
	// on a big endian machine this would print 0.12345...
	printf("direct:   %le\n", directDbl);
	
	// on a little endian machine *this* would print 0.12345...
	printf("reverse:  %le\n", reverseValue(onedotsomethingbytes));
	
	// Use the double's memory as data. This is equivalent to using 
	// the char array. It's also legal.
	printf("reverse:  %le\n", reverseValue((char *)&directDbl));
	
	// Try the ntohd with compile time decision.
	printf("ntohd:    %le\n", ntohd(directDbl));
	
    return 0;
}