负数的字节序转换?

Endian conversion for negative number?

目前我正在做一个网络项目,我正在将长数据(64 位)转换为大字节序,然后再发送到套接字上。为此,我使用 htobe64(x) 函数。在接收方客户端上,我使用 be64toh(x) 函数从大端字节序转换为主机字节序。这对于像 (132) 这样的正数很好,但是当数字为负数 (-132) 时,函数 returns 上面的一些模糊数字。我很困惑为什么即使我使用上面的标准函数也会发生这种情况。 目前正在 ubuntu (linux) 机器上测试客户端和服务器。

例如见下面的代码。

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;

输出为:

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

这对正数工作正常。

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

htobe64 returns类型uint64_t,不长。值 18446744073709551484 是二进制补码 -132 的无符号 64 位表示。 = 0xffffffffffffff7c

cout << "be64toh = " << be64toh(b) << endl;函数be64toh接受并且returnsbase64_t因此cout将位序列打印为无符号。因此,您看到的是位序列的无符号解释。一般来说,带符号的数字以 2 的补码方法表示(尽管它可能因硬件而异)。它适用于正数,因为带符号的位是 0,因此位序列是相同的。但是在负数的情况下,有符号位(最左边的位)是1,如果这样的位序列被解释为无符号整数,它会给你一个巨大的数字。

如果您将语句替换为以下示例:

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

它将整数重新解释为带符号的(长整数默认带符号),然后您将能够看到您想要的结果。

因此字节序转换没有问题,这只是打印例程根据变量类型进行解释的方式。