了解字节交换

时间:2017-11-19 21:47:37

标签: c byte endianness

我试图想办法为64位整数创建一个小端/大端转换(uint64_t),虽然我在网上找到了很多关于如何做到的答案,但没有一个解释究竟是怎么回事。例如,要获取整数的第n个字节,我发现了这个响应:

int x = (number >> (8*n)) & 0xff;

即使我理解了位移组件(向右移8n位),我也不知道&和0xff进来了,除了&是一个按位AND运算符。

那么,这种逻辑如何应用于64位整数的big-endian / little-endian字节交换方法呢?

提前谢谢。

1 个答案:

答案 0 :(得分:5)

最简单的想法是用十进制数字来比喻:

取数字308.它有三个数字,'3','0'和'8'。按照惯例,左边的数字比右边的数字更重要。但是惯例可能很容易就是另一种方式......数字可能是以相反的顺序写成的(例如,803)。

为什么这有关系?考虑计算机上数字的十六进制表示:0xabcd0123。在数学上严格意义上,可以将此数字视为4个基数-256个数字。 (即0xab,0xcd,0x01,0x23)。因此,字节顺序是关于在写入内存时对这些基数256位数进行排序的惯例。

Little-endian表示“将最低有效数字写入最低地址”; Big-endian意味着“将最重要的数字写入最低地址”。

那么,关于处理字节序的机制: 如果你想到上面的十进制例子,你会如何得到每个数字?通过取模数10(即,308%10 = 8)给出最低有效数字。第二个数字可以通过将数字除以10得到,然后取模10(即308/10 = 30; 30%10 = 0)等等。

对于计算机上的二进制数据,该过程完全相同,除了它被视为radix-256而不是radix-10之类的十进制数字。这是一些技巧的来源。

  1. 当使用2的幂的模数进行模数时​​,可以通过AND进行。设m = 256作为模数。因为m = 2到某个幂,x%m相当于x& (M-1)。这是一个数字事实,超出了这个答案的范围。
  2. 当用2的幂进行除法时,你可以通过右移来做。也就是说,让m = 256是我们的除数。因为m = 2到8次幂,所以x / m等于x>> 8。
  3. 因此,二进制特定于字节序的序列化完全使用上述过程:

    uint32_t val = 0xabcd0123;

    (val & 0xff)相当于(val % 256),并产生0x23。

    ((val >> 8) & 0xff)相当于((val / 256) % 256),并产生0x01。

    ((val >> 16) & 0xff)相当于(((val / 256)/256) % 256),并产生0xcd。

    等等。现在您可以访问数字/字节,只需选择存储它们的顺序即可。如上所述,“big endian =在最低地址最重要”,“little endian =在最低地址最不重要”。