比特序和字节序

7
我正在逐字节读取文件。
例如,我有这个字节:0x41(用十六进制表示为01000001)。
现在,我想要这个字节的前三位,即(010)。
我可以使用位逻辑来提取前三位,但我的问题是,这个字节的前三位是否独立于机器的字节序?(例如它们不能是001吗?)
谢谢。

位通常从右边开始计数,所以在您的例子中,010将是最后三位。我提到这一点是因为我认为大多数关于二进制操作的文档都认为最低位——代表1、2、4等数字的位——是第一位。 - T .
一个字内的位顺序没有普遍惯例。实际上,这取决于你使用它的用途。如果你在进行多字算术运算,则自然的顺序是最低有效位优先。然而,对于计算TCP/IP数据包的循环冗余校验(CRC),最高有效位优先更有意义。 - comingstorm
6个回答

10
另一种思考方式是,字节序仅适用于您可以单独读取项的组件的情况 - 由于您通常可以独立地从内存中读取32位整数的各个字节,如果您希望将这些字节解释为32位整数,则需要确保考虑到体系结构的字节序。

通常情况下,您无法从内存中读取字节的各个位,因此在内存架构方面实际上没有“位序”概念(我确定在硬件级别上有,但在软件级别不可见)。以下是您可能需要处理(或至少要知道)位序的几个领域:

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

  2. 某些硬件架构确实允许您寻址单个位(例如ARM Cortex M3),因此在这种情况下,如果要使用该功能,则需要知道架构如何安排位的寻址。

  3. 如果您要通过串行链接发送位 - 硬件接口通常会指定最高有效位或最低有效位首先“移出”线路。


7

字节序只适用于字节顺序,而不是位顺序。相应字节内的位顺序将保持不变。


3

是的,它们将相同。

在字节内部的位序通常只有在进行逐位I/O时才会成为问题,例如在读取通过串行线发送的数据流时。这些数据流一次只发送一个位,因此发送方和接收方需要就每个字节发送的位是从左到右还是从右到左达成一致。

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


1
有点混乱:除了串行通信,术语“第一位”没有任何意义,只有最左边(最重要)和最右边(最不重要)的位数。如果有人告诉你要提取“前三位”,那么就给他们一个耳光并问问他们的意思。即使是“Bit 0”这个术语也很模糊,它经常表示最不重要的、最右边的比特(2**0比特),但在某些比特字段中几乎同样经常用于表示最重要的、最左边的比特。字节中哪个位是“第一”位完全取决于您对位的操作。

完全同意“第一”和“最后”一点。然而,位0(不包括IP协议图表,这些图表会令人困惑)如果您将索引视为左移或经典的“位测试”指令(在许多CPU上实现),则相当清晰,其中位0表示从x & (1 << 0)bittest(x, 0)获取的任何位。 - Dwayne Robinson

1

C 语言中的位运算符是用于对 进行操作的。表达式 0x41U >> 5 将总是返回值 2(二进制中为 010)。


1
当一个字段使用一个字节的一部分或跨越从字节开始或结束(或两者都有)时,位顺序很重要。
例如:2个字节的数据首先是235(十进制),第二个是173(十进制),即十六进制EB和AD。
我想从第4位开始,到第12位的一个位域。所以,跳过3个位,从接下来的9个位中生成一个9位无符号整数。
我声称有4种可能的结果:
byteOrder, bitOrder * bigEndian, bigEndian 结果为十六进制0BA或十进制186 * littleEndian, littleEndian 结果为十六进制1BD或十进制445 * littleEndian, bigEndian 结果为十六进制05D或十进制93 * bigEndian, littleEndian 结果为十六进制1DE或十进制478
我已经在数据中看到了这4个中的前3个。大端、大端和小端、小端很容易解决。
处理这个问题的提示。
如果字节顺序是大端,请从左到右写下字节。 如果字节顺序是小端,请从右到左写下字节。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接