с++:带位位置的快速动作

с++: rapid actions with bits positions

有一个任务: 有2个号码:

例如:

src = 0b11010110 - 数字 №1 = 1, №2 = 2, №3 = 4, №4 = 6, №5 = 7

mask = 0b00001010 - 从 src

中提取数字 №1, №3

result = 0b01000100

你能告诉我你能多快做到这一点吗? 我写了下面的代码,但也许你可以做得更好?

int unzip_variant(const int src, const int mask)
{
    int unzipped = 0;

    int pos = 0;

    for (int index = 1; index <= с_size; index ++)
    {
        if (src & (1 << index))
        {
            pos += 1;

            if (mask & (1 << pos))
                unzipped |= (1 << index);
        }
    }

    return unzipped;
}

我希望,我正确理解了你的问题,并写下了这个解决方案:

// x: value, m: mask, for your dataset: unzip(0xd6, 0xa) -> 0x44
unsigned unzip(unsigned x, unsigned m) {
  unsigned bit, mm;
  for(mm = 0, bit = 1; bit <= x; bit <<= 1)
    if(bit & x)
      mm |= bit & m;
    else
      m <<= 1;
  return x & mm;
}

if 继续条件的可能有用的修改:

for(mm = 0, bit = 1; bit <= x && bit != 0; bit <<= 1)
  • bit != 0 - 如果 x 的符号位(最高)也包含数据
  • ,则很有用

通过实验获得最快的代码,我不能再快了。

int unzip_variants(
    const int   numbers,
    const int   variants
)
{
    int unzipped_variants = 0;

    int pos = 0;

    for (int index = 1; index <= с_size; index++)
    {
        pos += (variants >> index) & 1;
        unzipped_variants |= (((variants >> index) & 1) *
                                ((numbers >> pos) & 1)) << index;
    }

    //  for (int variants_index = 1; variants_index <= с_size; variants_index++)
    //  {
    //      if (variants & (1 << variants_index))
    //      {
    //          pos += 1;
    //
    //          if (numbers & (1 << pos))
    //              unzipped_variants |= (1 << variants_index);
    //      }
    //  }

    return unzipped_variants;
}