3

我的问题涉及字节序变化时的位操作。特别是我有一些代码可以读取uint32_t值的各个位并对其执行位操作。目的是 UTF-8 编码。它非常适合我的小端机器。

最近重新访问代码时,我突然意识到,就uint32_t值的位表示而言,我并没有考虑机器的字节顺序。所以我对这方面有一些疑问。

让我们假设一个示例代码只需要uint32_t保存在不同字节中的位 7-10。

uint32_t v;
v = 18341;
char c = (v &(uint32_t) 0x3C0)>>6;

对于 little endian,数字 18341 表示为0x47A5 或 二进制:

0100 01 11 10 10 0101

上面的代码应该给我们 1110 存储在 char

现在的问题是我们如何在 Big Endian 机器中实现这一点?相同的数字将以完全不同的方式表示0xA5470000或以二进制表示:

10 10 0101 0100 01 11 0000 0000 0000 0000

随着我们寻求的位处于完全不同的位置,甚至没有结果。

由于字节顺序不同,我们必须使用其他东西,而不是在&0x3C0的另一边使用。特别是因为我们需要一个字节的后续位,我们需要多个布尔操作,如下右图?

char c = ((v&(uint32_t)0xc0)>>6) | ((v&(uint32_t)0x300)>>6)

加起来。我的理解是否正确,在我们需要获取以二进制表示的整数值的连续位的情况下,我们需要对两种字节序情况执行不同的操作?

最后,有没有比我上面展示的更好的方法来实现相同的目标?也许我错过了一些完全明显的东西。

4

1 回答 1

1

否。如果您使用值(如 0x300)和语言运算符(<<、|、&),则无关紧要,因为值将根据机器表示。所以在你的情况下,你不需要担心这个问题。例如,当您将字节从文件复制到内存中时,您应该担心。

如果您直接处理内存表示,则可以在操作之前转换表示:

#if defined (BENDIAN)
   val = makelittle(val);
#endif
   manip_lendian(val);
#if defined (BENDIAN)
   val = makebig(val);
#endif

请参阅此答案

于 2012-07-11T07:16:21.750 回答