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——他想从e
r
位进入寄存器索引。因此,将
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