我想知道如何扭转这样的事情。那么有一个如何摆脱面具的mask
地方呢?auto mask = 1ULL << 20;
20
问问题
1680 次
8 回答
11
无循环
许多年前,当我为国际象棋引擎编写按位算术时,我发现了一个快速实现,它对您的要求很有用,它是无循环的。此方法将返回第一个1
位从右到左的位置(最低有效位):
inline unsigned int lsb(unsigned long long value)
{
if (!value)
return -1;
value &= -value;
unsigned int lsb = (unsigned) value | (unsigned) (value >> 32);
return (((((((((((unsigned) (value >> 32) != 0) << 1)
+ ((lsb & 0xffff0000) != 0)) << 1)
+ ((lsb & 0xff00ff00) != 0)) << 1)
+ ((lsb & 0xf0f0f0f0) != 0)) << 1)
+ ((lsb & 0xcccccccc) != 0)) << 1)
+ ((lsb & 0xaaaaaaaa) != 0);
}
int main()
{
unsigned long long x = 1ULL<<20;
cout << lsb(x) << endl;
}
输出
20
我想,我在这里找到了。
于 2013-04-22T06:16:57.927 回答
6
使用日志:
#include <iostream>
#include <cmath>
int main() {
auto mask = 1ULL << 20;
std::cout << log2(mask) << std::endl;
// edit out: std::cout << log(mask) / log(2) << std::endl;
return 0;
}
或循环和移位:
#include <iostream>
int main() {
auto mask = 1ULL << 20;
for (unsigned int c = 0; c < sizeof(mask) * 8 && mask; c++) {
mask >>= 1;
if (mask == 0)
std::cout << c << std::endl;
}
return 0;
}
于 2013-04-22T06:13:52.090 回答
5
If it's a 64-bit mask, you can compute it modulo 67 and do a table lookup.
To wit:
static int table[67] = {
-1, 0, 1,39, 2,15,40,23, 3,12,
16,59,41,19,24,54, 4,-1,13,10,
17,62,60,28,42,30,20,51,25,44,
55,47, 5,32,-1,38,14,22,11,58,
18,53,63, 9,61,27,29,50,43,46,
31,37,21,57,52, 8,26,49,45,36,
56, 7,48,35, 6,34,33};
int unmask(unsigned long long ull) {
return table[ull % 67];
}
于 2013-04-22T06:49:35.610 回答
1
//first if you want to make sure only 1 bit is "on" you can do that:
if ((mask & mask-1) != 0)
{
//you have more than 1 bit "on", deal with it...
}
//finding which bit is "on" can be achieve in a loop
int count 0;
while (mask > 1)
{
mask>>=1;
count++;
}
//At this point count will have the required value (20 in your example)
于 2013-04-22T06:22:51.157 回答
1
选项1:迭代
while (mask && !(mask & 1)) { mask>>=1; count++; }
选项 2:一次迭代多个位:
unsigned long long a=0xFFFFFFFFULL; int b=32;
while (mask>1) {
if (!(mask & a)) { count+=b; mask>>=b; }
b>>=1; mask>>=b;
}
选项 3:将掩码转换为双精度或浮点数并提取指数。
union {
struct {
int mantissa:23;
int exp:7;
int sign:1;
} s;
float f;
} u = { (float) mask };
return u.s.exp + 1;
于 2013-04-22T06:16:29.077 回答
1
一个简单的循环就可以了:
for (int bit = 0; bit < sizeof(mask) * 8; bit++)
{
if ((1ULL << bit) & mask)
std::cout << "Bit " << bit << " is set in the mask\n";
}
于 2013-04-22T06:14:20.320 回答
0
TMP 解决方案怎么样:
#include <iostream>
template < unsigned long long MASK >
struct MaskIndex
{
enum { i = MaskIndex < MASK / 2 >::i + 1 };
};
template <>
struct MaskIndex < 1 >
{
enum { i = 0 };
};
int main()
{
const unsigned long long mask = 1ULL << 20;
std::cout << MaskIndex < mask >::i << std::endl;
return ( 0 );
}
于 2013-04-22T06:45:25.893 回答
-1
你可以试试这个。。
if((1ULL<<20)&mask) {
cout << "20th bit is set";
}
于 2013-04-22T06:17:27.477 回答