C++ 隔离位并将其展平 问题
假设我有一个位掩码C++ 隔离位并将其展平 问题,c++,bit-manipulation,C++,Bit Manipulation,假设我有一个位掩码mask和一个输入n,例如 mask = 0x10f3 (0001 0000 1111 0011) n = 0xda4d (1101 1010 0100 1101) 我想1)隔离屏蔽位(从n中删除位,而不是在屏蔽中) 和2)将它们“展平”(去掉掩码中的零位,并将这些相同的移位应用于掩码) 尝试过的解决方案 a)在这种情况下,可以设计一系列特殊的位移位: result = (n & 0b10) | (n & 0b11110000) >> 2 |
mask
和一个输入n
,例如
mask = 0x10f3 (0001 0000 1111 0011)
n = 0xda4d (1101 1010 0100 1101)
我想1)隔离屏蔽位(从n
中删除位,而不是在屏蔽中)
和2)将它们“展平”(去掉掩码中的零位,并将这些相同的移位应用于掩码
)
尝试过的解决方案
a)在这种情况下,可以设计一系列特殊的位移位:
result = (n & 0b10) | (n & 0b11110000) >> 2 | (n & 0b1000000000000) >> 6
b)更一般地说,还可以迭代掩码的每一位,并一次计算一位结果
for (auto i = 0, pos = 0; i < 16; i++) {
if (mask & (1<<i)) {
if (n & (1<<i)) {
result |= (1<<pos);
}
pos++;
}
}
for(自动i=0,pos=0;i<16;i++){
if(mask&(1一种更有效的通用方法是在位上循环,但只处理掩码中的位数,删除if(mask&)(1这听起来很糟糕。你试图解决的实际问题是什么?一定有一个更简单的方法。对于预定义的位掩码,你可以在编译时用一些TMP生成移位。我读了5遍,仍然不明白展平位的意思。这个操作的真值表是什么?@SergeyA——他想从er
位进入寄存器索引。因此,将r
位想象为编号:r4
,r3
,r2
,r1
,r0
,在模式中从左到右。计算值时,就好像这些位都是连续的:r4r3r2r1r0
。这是一种常见的硬件,其中不同的东西是交错的,你必须为其中一个东西挑选位元。那么你想打包所选位元吗?这就是所谓的,
result = (n & 0b10) | (n & 0b11110000) >> 2 | (n & 0b1000000000000) >> 6
for (auto i = 0, pos = 0; i < 16; i++) {
if (mask & (1<<i)) {
if (n & (1<<i)) {
result |= (1<<pos);
}
pos++;
}
}
int mask = 0x10f3;
int n = 0xda4d;
int result = 0;
int m = mask, pos = 1;
while(m != 0)
{
// find rightmost bit in m:
int bit = m & -m;
if (n & bit)
result |= pos;
pos <<= 1;
m &= ~bit; // remove the rightmost bit from m
}
printf("%04x %04x %04x\n", mask, n, result);
10f3 da4d 0051
if (n & -m & m)
result |= pos;
pos <<= 1;
m &= m-1;
xxxxxxxxxxxx1000
xxxxxxxxxxxx0111