代码之家  ›  专栏  ›  技术社区  ›  jeremysprofile

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

  •  1
  • jeremysprofile  · 技术社区  · 6 年前

    我有一些需要转换的无符号32位big-endian整数,一旦找到正确的头,这就非常容易了:

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

    然而 endian.h 指定这些用于无符号整数。对于有符号整数,我真的不知道该怎么办,因为这类东西似乎没有头文件,而且我对C++中的位操作也不太熟悉。

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

    abcdefghijklmnopqrstuvwxyz012345
    

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

    yz012345qrstwx...
    

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

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

    2 回复  |  直到 6 年前
        1
  •  3
  •   rwp    6 年前

    正在尝试字节反转a 已签署 整数听起来不像是一个定义良好的算术运算,因为最高有效位的行为是整数符号的指示符,在处理整数变量时,将其移到其他位置没有多大意义。

    更有可能的是,您可能有一个表示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(...) 严格来说,依赖于实现。所以,再一次,我想问题是,字节反转a意味着什么 已签署 整数在数学上并不明确。

        2
  •  2
  •   Cuspy Code    6 年前

    只有当本机系统是little endian时,这才有意义,因为在big endian系统上将数据转换为带符号的little endian有什么意义?

    所以在一个小端系统上,只需将大端整数转换为无符号整数,使用 be32toh ,然后将结果强制转换为有符号整数。实际上,最好从一开始就将大端号表示为无符号,因为它的符号在小端号系统中没有意义。所以,只需转换无符号位,然后转换为有符号位。