将 32 位大端有符号整数转换为有符号小端整数

convert 32 bit big endian signed integer to signed little endian integer

本文关键字:符号 整数 转换      更新时间:2023-10-16

我有一些无符号的 32 位大端整数需要转换,一旦我找到正确的标头,这很容易:

#include <endian.h>
...
be32toh(some_int);

但是,endian.h指定这些用于无符号整数。对于有符号整数,我不确定该怎么做,因为它看起来没有用于此类事情的头文件,而且我对C++中的位操作并不熟悉。

编辑:由于对我的整数格式有一些混淆,让我解释更多。我有一个整数的形式

abcdefghijklmnopqrstuvwxyz012345

其中每个字符代表一个位。a位表示符号。我知道字节总是大端序,所以除了将字节移动到不同的顺序之外,比如

yz012345qrstwx...

我还需要一些方法来确保y位显示符号,而不仅仅是数字中的某个位。我。。。不知道该怎么做。

编辑:我的问题是我认为符号位总是按顺序排列,而事实并非如此。符号位始终是 MSB,这意味着如果您采用小端形式,则符号位将位于构成整数的字节的中间。

尝试对有符号整数进行字节反转听起来不像是定义明确的算术运算,因为最高有效位的行为是整数符号的指示器,并且在操作整数变量时将其移动到其他地方没有多大意义。

更有可能的是,您可能有表示 32 位有符号整数的 4 个字节序列,但需要进行字节反转才能在不同的 CPU 字节序之间进行转换。为此,您可以简单地将数量视为未签名的数量,并让be32toh()为您完成工作:

(int)be32toh((unsigned)some_int);

或者,稍微安全一点:

(int32_t)be32toh((uint32_t)some_int);

这是因为转换操作在应用于相同位深度的整数时,有效地保持内存中的表示形式不变。这在执行字节反转时忽略了符号的重要性(以及与有符号整数的二进制补码表示相关的任何微妙之处(。我不确定这种行为是否受到C标准(也许是语言律师的问题(的保证,但这可能是一种非常普遍的行为。www.cplusplus.com 的描述表明,如果您的系统对其有符号整数使用二进制补码表示(这很常见(,那么(uint32_t)some_int中的有符号到无符号转换将做正确的事情。但是,严格来说,(int32_t)be32toh(...)中对有符号到无符号转换的精确解释取决于实现。所以,再一次,我认为字节反转有符号整数意味着什么的问题在数学上并不是明确的。

这只有在本机系统是小端序时才有意义,因为在大端序系统上将数据转换为有符号的小端序有什么意义?

因此,在小端系统上,您需要做的就是将大端整数转换为无符号,使用be32toh进行转换,然后将结果转换为有符号整数。实际上,最好从一开始就将大端表示为无符号,因为它的符号在小端系统中没有意义。因此,只需转换无符号位,然后转换为有符号。