如何在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
依次屏蔽每个单独的源位,按位与 &
与 a
和 b
从源变量,<< i
和 << (i + 1)
将位移动到目标位置。然后所有内容都按位或运算在一起 |
.
澄清目标位置的转变:
& (1U << i)
将索引 i
处的位与输入 a
和 b
隔离开来。该位 already in index i
,因此 following shift << i
for a
将其放入索引 i + i
,b
的移位 << (i + 1)
将其放在索引 i + (i + 1)
中。因此,索引 i
的位最终在 a
的索引 2i
和 b
.
的索引 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
开始,因此移位直接显示目标索引(以隐藏源索引和需要修改参数为代价)。
我有两个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
依次屏蔽每个单独的源位,按位与 &
与 a
和 b
从源变量,<< i
和 << (i + 1)
将位移动到目标位置。然后所有内容都按位或运算在一起 |
.
澄清目标位置的转变:
& (1U << i)
将索引 i
处的位与输入 a
和 b
隔离开来。该位 already in index i
,因此 following shift << i
for a
将其放入索引 i + i
,b
的移位 << (i + 1)
将其放在索引 i + (i + 1)
中。因此,索引 i
的位最终在 a
的索引 2i
和 b
.
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
开始,因此移位直接显示目标索引(以隐藏源索引和需要修改参数为代价)。