整理一下&、||、!的奇技淫巧
1 x&(x-1)是什么意思京东有一道笔试题
#includeusing namespace std; int func(int x) { int count = 0; while (x) { count++; x = x & (x - 1); } return count; } int main(int argc, char** argv) { cout << func(2015) << endl; return 0; }
就是x的二进制与x-1的二进制进行与运算;
再深挖一步,x-1的二进制就是把x的二进制的最右侧一个1变成0。
第一次 x & (x - 1)的结果就是把x最右侧的第一个1变成0(去掉1),再将结果赋值给x,计数器++;
......
所以 x & (x - 1)是统计x的二进制中有多少个1
上述代码结果
2015比1024大(2的10次方),但是小于2048(2的11次方)。
2 求一个数最右侧的1是哪一位例如:
1 = (001)------->0 (从第0位开始计数,1在第0位)
2 = (010)------->1 (从第0位开始计数,1在第1位)
3 = (011)------->0 (从第0位开始计数,1在第0位)
4 = (100)------->2 (从第0位开始计数,1在第2位)
5 = (101)------->0 (从第0位开始计数,1在第0位)
......
首先从最低位开始判断,怎么判断呢?
想到与或非运算符。当x=1时,x&1才是1
#includeusing namespace std; int func(int x) { int count = 0; int res = 1; while (1) { if (x & res) { break; } count++; res = res << 1; } return count; } int main(int argc, char** argv) { cout << func(1) << endl; cout << func(2) << endl; cout << func(3) << endl; cout << func(4) << endl; cout << func(5) << endl; return 0; }
结果
如果要计算具体是多少,用2累乘即可。
3 求一个数最右侧的0是哪一位例如:
1 = (001)------->1 (从第0位开始计数,1在第1位)
2 = (010)------->0 (从第0位开始计数,1在第0位)
3 = (011)------->2 (从第0位开始计数,1在第2位)
4 = (100)------->0 (从第0位开始计数,1在第0位)
5 = (101)------->1 (从第0位开始计数,1在第1位)
......
#includeusing namespace std; int func(int n) { int res = 0; while (n & 1) { n = n >> 1; res++; } return res; } int main(int argc, char** argv) { cout << func(1) << endl; cout << func(2) << endl; cout << func(3) << endl; cout << func(4) << endl; cout << func(5) << endl; return 0; }
结果
4 求一个数最左侧的1是哪一位#includeusing namespace std; int func(int n) { int pos=-1; while (n) { n>>=1; pos++; } return pos; } int main(int argc, char** argv) { cout << func(1) << endl; cout << func(2) << endl; cout << func(3) << endl; cout << func(4) << endl; cout << func(5) << endl; return 0; }
结果
5 x%y=x&(y-1)这个是在leveldb源码中看到的三行代码
const int align = (sizeof(void*) > 8) ? sizeof(void*) : 8;
static_assert((align & (align - 1)) == 0,
"Pointer size should be a power of 2");
size_t current_mod = reinterpret_cast(alloc_ptr_) & (align - 1);
第一句:指针大小是4/8(32机器人是4字节,64位机器是8字节),所以align的值总是8
第二句:这是一句断言。如果一个数x,是2的n次方,那么这个数用二进制表示时其最高位为1,其余位为0。则(x-1)的二进制就是01111111.....1。则其与x与之后就是0,所以x&(x-1)) == 0为真,表明x是2的n次方,否则x不是2的n次方。
第三句:y & (x - 1),对应的y % x
注意:x必须是2的次幂。
未完待续......
参考:HashMap算法:x%y=x&(y-1)_程序员阿坤的博客-CSDN博客



