首页 > 解决方案 > 将 32 位大端有符号整数转换为有符号小端整数

问题描述

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

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

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

编辑:由于我的整数格式有些混乱,让我解释一下。我有一个整数形式

abcdefghijklmnopqrstuvwxyz012345

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

yz012345qrstwx...

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

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

标签: c++bit-manipulationendianness

解决方案


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

更有可能的是,您可能有代表 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(...)严格来说,是依赖于实现的。因此,我再次认为,对有符号整数进行字节反转意味着什么的问题在数学上并不是明确的。


推荐阅读