Search code examples
c++linuxendianness

Endian conversion for negative number?


Currently I am working on a networking project where I am converting the long data (64 bits) to big endian before sending on a socket. For this I am using htobe64(x) function. And on receiving side client I am converting from big endian to host machine byte order using be64toh(x) function. This is working fine for positive numbers like (132) but when number is negative (-132) above function returns some obscure number. I am confused why this is happening even when I am using standard functions like above. Currently testing on ubuntu (linux) machine for both client and server.

For example see below code.

long a = -132;

cout << "=========" << endl;
cout << "a = " << a << endl;
cout << "htobe64 = " << htobe64(a) << endl;
long b = htobe64(a);
cout << "be64toh = " << be64toh(b) << endl;
cout << "=========" << endl;

The output is :

=========
a = -132
htobe64 = 9007199254740991999
be64toh = 18446744073709551484
=========

This is working fine for positive number.

=========
a = 132
htobe64 = 9511602413006487552
be64toh = 132
=========

Solution

  • The line cout << "be64toh = " << be64toh(b) << endl; the function be64toh accepts and returns base64_t therefore cout prints the bit sequence as unsigned. Therefore what you see the unsigned interpretation of the bit sequence. In general signed numbers are represented in the 2's compliment method (although it can vary based on hardware). It works for positive numbers because the signed bit is 0 and therefore the bit sequence is the same. But in case of a negative number the signed bit (the leftmost bit) is 1, and if such a bit sequence is interpreted as an unsigned integer, it will get you a huge number.

    If you replace your statement with the following example:

    cout << "be64toh = " << (long) be64toh(b) << std::endl;

    which reinterprets the integer as being signed (long is by default signed), then you will be able to see your desired result.

    Therefore there is no issues in the endian conversion, it's just the way the printing routine interprets based on the type of the variable.