我有一组带有按位或相加值的组合:
enum EventType_e
{
EventType_PING = 1,
EventType_PANG = 2,
EventType_PONG = 4,
EventType_PUNG = 8
};
我预计此枚举最多将包含15-20个项目。接收到这些枚举值之一后,我希望能够将其映射到 vector ,但是我不想让它具有稀疏数组,而是将这些值折叠起来。将1,2,4,8,16,32映射到1,2,3,4,5,6的最佳方法是什么(即在2 ^ x = 1,2 ^ x = 2,2中找到'x' ^ x = 4、2 ^ x = 8等)
最佳答案
大多数现代CPU架构都有操作码来发现数字中最高或最低有效的非零位(例如x86上的BSF and BSR)。这些在某些编译器上也可用作内在函数,例如Microsoft和Intel编译器上的_BitScanForward
和_BitScanReverse
。
上面的位扫描是最快的解决方案。对于更便携的解决方案,向右移动直到钻头从末端掉下来:
int i;
for (i = 0; n >>= 1; ++i) { }
请注意,这将返回0、1、2、3,这比1、2、3、4更适合 vector 索引。
一个更复杂但更快的便携式解决方案是二进制印章:
// Logically, we initialise i to 0, and add n - 1 at the end. Initialising
// to -1 avoids the subtraction. This is splitting hairs somewhat, and who
// knows — initialising to -1 instead of zero might be slow!
int i = -1;
if (n >> 16) { n >>= 16; i += 16; }
if (n >> 8) { n >>= 8; i += 8; }
if (n >> 4) { n >>= 4; i += 4; }
if (n >> 2) { n >>= 2; i += 2; }
i += n;
关于c++ - 将位掩码值(1、2、4、8等)映射到 vector 索引(1、2、3、4等)的有效方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5523227/