如何在C中将两个8位的数据排列成一个16位的数据?

How to arrange the data of two 8-bits in to a single 16-bit in C?

我有两个8位数据,

1st 8-bit= {DA7 DA6 DA5 DA4 DA3 DA2 DA1 DA0}

2nd 8-bit= {DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0}

我想将这两个数据合并成一个 16 位数据,按照下面的安排,

Expected result = {DB7 DA7 DB6 DA6 DB5 DA5 DB4 DA4 DB3 DA3 DB2 DA2 DB1 DA1 DB0 DA0}.

在 C 中是否有任何直接的 logic/method 实现此目的?

搜索关键字:“交错位”

有很多方法可以做到,从“显而易见”的方法到乘以幻数。参见 bit twiddling hacks

适用于 8 位整数的明显方式:

uint16_t interleave_bits(const uint8_t a, const uint8_t b) {
    uint16_t result = 0;
    for (int i = 0; i < 8; ++i) {
        result |= (a & (1U << i)) << i | (b & (1U << i)) << (i + 1);
    }
    return result;
}

在循环内,1U << i 依次屏蔽每个单独的源位,按位与 &ab 从源变量,<< i<< (i + 1) 将位移动到目标位置。然后所有内容都按位或运算在一起 |.

澄清目标位置的转变:

& (1U << i) 将索引 i 处的位与输入 ab 隔离开来。该位 already in index i,因此 following shift << i for a 将其放入索引 i + ib 的移位 << (i + 1) 将其放在索引 i + (i + 1) 中。因此,索引 i 的位最终在 a 的索引 2ib.

的索引 2i+1

等效(但效率较低)的实现是:

uint16_t interleave_bits(uint8_t a, uint8_t b) {
    uint16_t result = 0;
    for (int i = 0; i < 8; ++i, a >>= 1, b >>= 1) {
        result |= (a & 1U) << (2*i) | (b & 1U) << (2*i + 1);
    }
    return result;
}

在第二个解决方案中,源位总是从索引 0 开始,因此移位直接显示目标索引(以隐藏源索引和需要修改参数为代价)。