字节序可以指一个字节的位顺序吗?

我正在阅读Chris Adamson撰写的“学习核心音频:适用于Mac和iOS的音频编程实践指南”,并且作者一度将big-endian描述为:

字节或字的高位在数值上比低位更重要。

但是,直到现在我虽然大小端的问题只适用于字节顺序而不是位顺序。 无论我们是在谈论小端还是大端系统,一个字节都具有相同的位顺序(从左到右)。 我错了吗? 作者错了吗? 还是我误解了他的观点?

由于您不能单独地对一个字节内的位进行寻址,因此通常没有“位字节式”的概念。

存在“位顺序”之类的唯一意义是将位分配给位域的顺序。 例如,在:

union { struct { unsigned char a:4; unsigned char b:4; } bf; unsigned char c; }; 

取决于实现, bf.a的表示可以占用c的高四位或c的低四位。 位域成员的顺序是否与字节顺序匹配是实现定义的。

这不是对所述问题的回答 – 已经有其他人已经很好地回答了 – 但是一个脚注解释了一些术语,希望它能澄清相关的概念。 特别是,这根本不是特定于c的。


  • 字节顺序和字节顺序

    当大于字节的值被存储或序列化为多个字节时,存储组件字节的顺序的选择称为字节顺序字节顺序字节顺序

    从历史上看,有三个字节顺序在使用: “ big-endian ”“ little-endian ”“ PDP-endian ”“ middle-endian ”

    Big-endianlittle-endian字节顺序名称是从它们对字节排序的方式派生出来的:big-endian首先放置最重要的字节(影响逻辑值的字节最多),连续字节按重要性递减顺序排列; 而little-endian将最低有效字节放在第一位,连续字节按重要性递增。

    请注意,整数类型和浮点类型的字节顺序可能不同; 它们甚至可以在单独的硬件单元中实现。 但是,在大多数硬件上,它们具有相同的字节顺序。

  • 位顺序

    位顺序与字节序非常相似,只是它涉及单个位而不是字节。 这两个概念是相关的,但并不相同。

    位顺序仅在位序列化时有意义,例如通过串行或SPI或I 2 C总线; 相继。

    在并行使用的较大组中引用位时,作为一个单元 ,如字节或字,则没有顺序:只有标记重要性 。 (这是因为它们作为一个组被并行地,而不是一个接一个地连续访问和操作,没有特定的顺序。它们作为一个组的解释产生了不同的重要性,我们人类可以为它们标记或编号易于参考。)

  • 有意义

    当一组位被视为二进制值时,存在最低有效位最高有效位 。 这些名称源自如下事实:如果更改最低有效位,则位组的值将以可能的最小量更改; 如果更改最高有效位,则位组的值将以可能的最大量(通过单个位更改)更改。

    假设你有一个五位组,比如abcde ,形成一个五位无符号整数值。 如果a是最重要的,并且是最不重要的,并且其他三个是按重要性递减的顺序,则无符号整数值是
    value = a ·2 4 + b ·2 3 + c ·2 2 + d ·2 1 + e ·2 0

    = 16 a + 8 b + 4 c + 2 d + e

    换句话说, 位重要性来自一组位的数学(或逻辑)解释,并且完全独立于某些总线上的位可能被序列化的顺序,也来自任何人类指定的标签或数字。 。

    对于逻辑上构造数值的所有位组都是如此,即使对于浮点数也是如此。

  • 位标签或位编号

    例如,为了便于在文档中引用,标记各个位通常很有用。 这基本上是武断的; 事实上,我在上面的例子中使用了字母af 。 更常见的是,数字比字母更容易 – 用单个字母标记超过27位并不容易。

    有两种方法用数字标记位。

    目前最常见的是根据它们的重要性来标记位,位0指的是最低有效位。 这很有用,因为位i的逻辑值为2 i

    在某些体系结构的文档中,如IBM的POWER文档,最重要的位标记为0,按重要性降序排列。 在这种情况下,位的逻辑值取决于该单元中的位数。 如果一个单元有N位,则位i的逻辑值为2 N -i-1

    虽然这种排序可能会感觉很奇怪,但这些架构都是大端的,人们只需记住/假设最重要的架构首先出现在这些系统上。

    但请记住,这是一个完全随意的决定,在这两种情况下,文档都可以使用其他位标记方案编写,而不会对系统的实际性能产生任何影响。 这就像是选择是从左到右,还是从右到左(或从上到下,就此而言): 只要您了解并理解惯例 ,内容就不会受到影响。

虽然字节顺序和位标记之间存在某种相关性,但上述所有四个概念都是分开的。

字节顺序和位标记之间存在相关性 – 在某种意义上,许多大端硬件的文档使用位标记,其中最重要的位是位零 – 但这仅仅是因为人类选择了。

在c中 ,C编译器在结构中包含位域的顺序因编译器和体系结构而异。 完全没有C标准规定。 因此,将二进制文件读入具有位域的结构类型通常是个坏主意。 (即使它适用于某些特定的机器和编译器,也不能保证它适用于其他机器;通常,它不会。所以,它肯定会使代码不那么便携。)而是读入缓冲区和unsigned char数组,并使用辅助访问器函数使用位移( <<>> ),二进制ors( | )和掩码(二进制和, & )从数组中提取位字段。

除非您正在使用允许您分别寻址位的奇异系统,否则按位顺序的字节的“字节序”并不是真正关注的问题。 在决定如何通过线路传输数据时,这可能是一个问题,但这个决定通常是在硬件级别做出的。

音频

就与音频流的相关性而言,它非常重要。 负责将数字音频流转换为模拟音频信号的硬件可以预期流中的比特处于特定顺序。 如果他们错了,声音可能会完全被打破。 也许你的书的作者详细阐述了这一点? 无论如何,正如我之前提到的,这通常是在硬件级别决定的,并且在用户甚至内核级别进行编程时并不是真正的问题。 通常,行业标准将定义两个硬件如何将数据相互传输。 只要你的所有硬件都同意bit endian,那么一切都很好。

进一步阅读维基百科。

字节内的位顺序没有意义,字节内的位不可寻址,因此您无法定义此位的顺序以将其用作字节序定义的参考。 与位不同,字节是可寻址的,因此我们可以使用地址顺序作为参考来定义小端或大端的含义。

你可能会得到Left shift <<Right Shift >>逐位运算符间接暗示在一个字节内有一个定义的位顺序的印象,但事实并非如此。 这两个术语基于抽象字节表示,其中最低位位于右侧,位Left shift时值越高,但根据定义, Left shift与乘以2具有相同的效果, Right shift具有相同的效果除以2(对于无符号整数)。