[英]Bit manipulation of integers depending on endianess
当endianess改变时,我的问题涉及位操作。 特别是我有一些代码可以读取uint32_t
值的各个位并对它们执行位操作。 目的是UTF-8编码。 它适用于我的小端机器。
最近重新审视了代码,我突然意识到,就uint32_t
值的位表示而言,我并没有考虑机器的endianess。 所以我对这方面有一些疑问。
让我们假设一个示例代码, uint32_t
保存在不同字节中的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情况执行不同的操作吗?
最后有没有比我上面展示的更好的方法来实现同样的东西? 也许我错过了一些非常明显的东西。
不。如果您使用的是值(如0x300)和语言运算符(<<,|,&),则无关紧要,因为该值将根据机器表示。 因此,在您的情况下,您不必担心这个问题。 例如,当您将文件中的字节复制到内存中时,您应该担心。
如果直接处理内存表示,可以在操作之前转换表示:
#if defined (BENDIAN)
val = makelittle(val);
#endif
manip_lendian(val);
#if defined (BENDIAN)
val = makebig(val);
#endif
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.