根据字节顺序对整数进行位操作

时间:2012-07-11 07:11:07

标签: c bit-manipulation endianness

我的问题涉及结束性变化时的位操作。特别是我有一些代码读取uint32_t值的各个位并对它们执行位操作。目的是UTF-8编码。它适用于我的小端机。

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

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

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

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

0100 01 11 10 10 0101

以上代码应该给我们存储在char

中的1110

现在问题是我们将如何在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)

总结。我的理解是正确的,在我们需要获得以二进制表示的整数值的连续位的情况下,我们需要对两个endianess情况执行不同的操作吗?

最后是否有更好的方法来实现与上面展示的相同的东西?也许我错过了一些非常明显的东西。

1 个答案:

答案 0 :(得分:1)

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

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

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

另外see this answer