#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;
}
I2luY2x1ZGU8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKLyoqIGNvcHkgdGhlIGJ5dGVzIGF0IGRhdGEgZGlyZWN0bHkgaW50byBhIGRvdWJsZS4gCiAgICBhbmQgcmV0dXJuIHRoYXQuCiovCmRvdWJsZSBkaXJlY3RWYWx1ZShjb25zdCBjaGFyICpkYXRhKQp7Cglkb3VibGUgcmVzdWx0OwoJY2hhciAqZGVzdCA9IChjaGFyICopJnJlc3VsdDsKCQoJbWVtY3B5KGRlc3QsIGRhdGEsIHNpemVvZihkb3VibGUpKTsKCQoJcmV0dXJuIHJlc3VsdDsKfQoKLyoqIGNvcHkgdGhlIGJ5dGVzIGF0IGRhdGEgaW50byBhIGRvdWJsZSwgcmV2ZXJzaW5nIHRoZQogICAgYnl0ZSBvcmRlciwgYW5kIHJldHVybiB0aGF0LgoqLwpkb3VibGUgcmV2ZXJzZVZhbHVlKGNvbnN0IGNoYXIgKmRhdGEpCnsKCWRvdWJsZSByZXN1bHQ7CgkKCWNoYXIgKmRlc3QgPSAoY2hhciAqKSZyZXN1bHQ7CgkKCWZvcihpbnQgaT0wOyBpPHNpemVvZihkb3VibGUpOyBpKyspIAoJewoJCWRlc3RbaV0gPSBkYXRhW3NpemVvZihkb3VibGUpLWktMV07Cgl9CglyZXR1cm4gcmVzdWx0Owp9CgovKiogQWRqdXN0IHRoZSBieXRlIG9yZGVyIGZyb20gbmV0d29yayB0byBob3N0LgogICAgT24gYSBiaWcgZW5kaWFuIG1hY2hpbmUgdGhpcyBpcyBhIE5PUC4KCVRoZXJlIGlzIG5vIGVycm9yIGhhbmRsaW5nIAoqLwpkb3VibGUgbnRvaGQoZG91YmxlIHNyYykKewojCWlmCQkhZGVmaW5lZChfX0ZMT0FUX1dPUkRfT1JERVJfXykgXAoJCXx8CSFkZWZpbmVkKF9fT1JERVJfTElUVExFX0VORElBTl9fKQojCQllcnJvciAib29wczogdW5rbm93biBieXRlIG9yZGVyIgojCWVuZGlmCgojCWlmIF9fRkxPQVRfV09SRF9PUkRFUl9fID09IF9fT1JERVJfTElUVExFX0VORElBTl9fCgkJcmV0dXJuIHJldmVyc2VWYWx1ZSgoY2hhciAqKSZzcmMpOwojCWVsc2UKCQlyZXR1cm4gc3JjOwojCWVuZGlmCn0KCmludCBtYWluKCkgCnsKCS8vIGJpZyBlbmRpYW4sIGkuZS4gbmV0d29yayBieXRlIG9yZGVyCgljb25zdCBjaGFyIG9uZWRvdHNvbWV0aGluZ2J5dGVzW10KCQkJCT0gezB4M0YsIDB4RjMsIDB4QzAsIDB4Q0EsIDB4NDIsIDB4ODMsIDB4REUsIDB4MUJ9OwoKCWRvdWJsZSBkaXJlY3REYmwgPSBkaXJlY3RWYWx1ZShvbmVkb3Rzb21ldGhpbmdieXRlcyk7CQkJCgkvLyBvbiBhIGJpZyBlbmRpYW4gbWFjaGluZSB0aGlzIHdvdWxkIHByaW50IDAuMTIzNDUuLi4KCXByaW50ZigiZGlyZWN0OiAgICVsZVxuIiwgZGlyZWN0RGJsKTsKCQoJLy8gb24gYSBsaXR0bGUgZW5kaWFuIG1hY2hpbmUgKnRoaXMqIHdvdWxkIHByaW50IDAuMTIzNDUuLi4KCXByaW50ZigicmV2ZXJzZTogICVsZVxuIiwgcmV2ZXJzZVZhbHVlKG9uZWRvdHNvbWV0aGluZ2J5dGVzKSk7CgkKCS8vIFVzZSB0aGUgZG91YmxlJ3MgbWVtb3J5IGFzIGRhdGEuIFRoaXMgaXMgZXF1aXZhbGVudCB0byB1c2luZyAKCS8vIHRoZSBjaGFyIGFycmF5LiBJdCdzIGFsc28gbGVnYWwuCglwcmludGYoInJldmVyc2U6ICAlbGVcbiIsIHJldmVyc2VWYWx1ZSgoY2hhciAqKSZkaXJlY3REYmwpKTsKCQoJLy8gVHJ5IHRoZSBudG9oZCB3aXRoIGNvbXBpbGUgdGltZSBkZWNpc2lvbi4KCXByaW50ZigibnRvaGQ6ICAgICVsZVxuIiwgbnRvaGQoZGlyZWN0RGJsKSk7CgkKICAgIHJldHVybiAwOwp9