给出一个整数
I
和一个位掩码M
,从M
中获得I
的对应值。例如,如果I
为0x11111
,而M
为0xff0
,则对应值为0x11
我可以通过:
&
和I
之间进行M
操作但是这种方式有点慢,尤其是在步骤2中。我想要一种更有效的方法来解决此问题。
答案 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机器(BSF
,AND
和SHR
)中仅执行3条汇编指令。