【问题标题】:bit ordering and endianess位排序和字节序
【发布时间】:2010-04-14 07:08:14
【问题描述】:

我正在逐字节读取文件。

比如说我有这个字节:0x41 (0100 0001) 以十六进制表示。

现在,我想要这个字节的前三位,即 (010)。

我可以使用按位逻辑来提取前三位,但我的问题是前三位是否与机器的字节序无关。(即它们不能是 001)?

谢谢,

【问题讨论】:

  • 位通常从右开始计算,因此 010 将是您示例中的最后三位。我之所以提到这一点,是因为我相信大多数关于位操作的文档都认为最低位——代表 1、2、4、...的位——是第一位。
  • 字内的位顺序没有通用约定。在实践中,这取决于您使用它的目的。如果你在做多字算术,自然排序是 LSB 优先。但是,对于计算 TCP/IP 数据包的 CRC,MSB 优先更有意义。

标签: c bit-manipulation endianness


【解决方案1】:

另一种思考方式是,仅当您可以单独读取项目的组件时才适用字节顺序 - 因为您通常可以从内存中独立读取 32 位 int 的各个字节,如果您想解释这些字节作为 32 位 int,您无需确保考虑架构的字节序。

通常您无法从内存中读取一个字节的各个位,因此就内存架构而言,确实没有“位字节序”的概念(我确信在硬件级别有,但不是您可以在软件级别看到的东西)。您可能需要处理(或至少了解)位字节序的几个方面:

  1. 编译器存储位字段位的顺序取决于编译器(并且不一定与硬件平台的字节序有关 - 不同的编译器可能对同一平台的位字段排序不同 -可以使用命令行选项以一种或另一种方式配置编译器,类似于 char 可能设置为有符号或无符号的方式)。但是,C 位域确实与硬件寻址无关。

  2. 1234563功能。
  3. 如果您通过串行链路发送位 - 硬件接口通常会指定是首先在线路上“移出”最高有效位还是最低有效位。

【讨论】:

    【解决方案2】:

    字节顺序仅适用于字节顺序,不适用于位顺序。相应字节内的位顺序将相同。

    【讨论】:

      【解决方案3】:

      是的,它们将是相同的。

      字节内的位排序通常仅在您进行逐位 I/O 时才会出现问题,例如在读取通过串行线路发送的数据流时。那些确实一次发送一个比特,因此发送者和接收者需要就每个字节的从左到右还是从右到左发送比特达成一致。

      对于文件和内存访问,字节内的位顺序不会改变。

      【讨论】:

        【解决方案4】:

        有点混乱:-)。除了在串行通信中,术语“第一位”没有任何意义,只有最左边(最高有效)和最右边(最低有效)位。如果有人告诉你提取“前三位”,那就给他们一记耳光,问他们是什么意思。即使术语“位 0”也是模棱两可的,它通常表示最低有效位、最右边位(2**0 位),但几乎同样经常用于表示某些位域中的最高有效位、最左边位.哪个位是字节中的“第一个”位完全取决于您对这些位所做的操作。

        【讨论】:

        • 完全同意“第一”和“最后”的观点。如果您考虑根据左移或经典“位测试”指令(在许多 CPU 上实现)进行索引,位 0(不包括 IP 协议图,这会造成不必要的混淆)非常清楚,位 0 表示您从中获得的任何位x & (1 << 0)bittest(x, 0).
        【解决方案5】:

        C 中的位运算符被定义为处理。表达式0x41U >> 5 将始终给出值 2(二进制,010)。

        【讨论】:

          【解决方案6】:

          当一个字段使用一个字节的一部分,或者跨越一个字节的开始或结束(或两者)的字节时,位顺序很重要。

          示例:2 个字节的数据,前 235(十进制)后 173(十进制),即十六进制 EB 和 AD。

          我想要一个从第 4 位开始到第 12 位的位域。所以,跳过 3 位,从接下来的 9 位生成一个 9 位无符号整数。

          我声称有 4 种可能的结果:

          字节顺序,位顺序 * bigEndian, bigEndian 结果为十六进制 0BA 或十进制 186 * littleEndian, littleEndian 结果为十六进制 1BD 或十进制 445 * littleEndian, bigEndian 结果为十六进制 05D 或十进制 93 * bigEndian, littleEndian 结果为十六进制 1DE 或十进制 478

          我在数据中看到了这 4 个中的前 3 个。大,大,小,小都很容易解决。

          处理此问题的提示。

          如果字节顺序是大端,从左到右写下字节。 如果字节顺序是小端,则从右向左写下字节。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-02-12
            • 2010-11-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-01-13
            • 1970-01-01
            • 2020-10-09
            相关资源
            最近更新 更多