如何有效地将位掩码的对应值转换为整数?

时间:2018-09-21 09:41:37

标签: c

  

给出一个整数I和一个位掩码M,从M中获得I的对应值。例如,如果I0x11111,而M0xff0,则对应值为0x11

我可以通过:

  1. &I之间进行M操作
  2. 计算右移多少位
  3. 进行右移

但是这种方式有点慢,尤其是在步骤2中。我想要一种更有效的方法来解决此问题。

1 个答案:

答案 0 :(得分:1)

我不知道是否有更有效的方法。我一直都像你一样但是,请考虑通常可以通过一条CPU指令来计算要右移多少位(第二步)。必须根据本能的指令完成操作,具体取决于您的系统。

在Windows上,此操作由_BitScanForward()提供,而在GCC上,此操作由__builtin_ctz()提供。

有关更多详细信息,请参见this answer

例如,您的问题的可能的Windows实现可能是:

#include <Windows.h>

unsigned int maskandshift(unsigned int m, unsigned int i) {
    unsigned int shift;
    // _BitScanForward returns 0 if the mask is zero.
    // You may prefer the actual number of 0, here:
    if (m == 0)
        shift = sizeof(i) * CHAR_BIT;
    else {
        DWORD trailing_zero;
        _BitScanForward(&trailing_zero, (DWORD)m);
        shift = (unsigned int)trailing_zero;
    }
    return (m & i) >> shift;
}

在Release配置中,此功能被编译为检查是否为零,然后在x64机器(BSFANDSHR)中仅执行3条汇编指令。