• 【c/c++学习】与或非的奇技淫巧


    整理一下&、||、!的奇技淫巧

    1 x&(x-1)是什么意思

    京东有一道笔试题

    1. /*************************************************************************
    2. > File Name: test.cpp
    3. > Author: Winter
    4. > Created Time: 2022年08月07日 星期日 16时12分42秒
    5. ************************************************************************/
    6. #include
    7. using namespace std;
    8. int func(int x)
    9. {
    10. int count = 0;
    11. while (x)
    12. {
    13. count++;
    14. x = x & (x - 1);
    15. }
    16. return count;
    17. }
    18. int main(int argc, char** argv)
    19. {
    20. cout << func(2015) << endl;
    21. return 0;
    22. }

    就是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

    1. #include
    2. using namespace std;
    3. int func(int x)
    4. {
    5. int count = 0;
    6. int res = 1;
    7. while (1)
    8. {
    9. if (x & res) {
    10. break;
    11. }
    12. count++;
    13. res = res << 1;
    14. }
    15. return count;
    16. }
    17. int main(int argc, char** argv)
    18. {
    19. cout << func(1) << endl;
    20. cout << func(2) << endl;
    21. cout << func(3) << endl;
    22. cout << func(4) << endl;
    23. cout << func(5) << endl;
    24. return 0;
    25. }

    结果

    如果要计算具体是多少,用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位)

    ......

    1. #include
    2. using namespace std;
    3. int func(int n) {
    4. int res = 0;
    5. while (n & 1) {
    6. n = n >> 1;
    7. res++;
    8. }
    9. return res;
    10. }
    11. int main(int argc, char** argv)
    12. {
    13. cout << func(1) << endl;
    14. cout << func(2) << endl;
    15. cout << func(3) << endl;
    16. cout << func(4) << endl;
    17. cout << func(5) << endl;
    18. return 0;
    19. }

    结果

    4  求一个数最左侧的1是哪一位

    1. #include
    2. using namespace std;
    3. int func(int n)
    4. {
    5. int pos=-1;
    6. while (n)
    7. {
    8. n>>=1;
    9. pos++;
    10. }
    11. return pos;
    12. }
    13. int main(int argc, char** argv)
    14. {
    15. cout << func(1) << endl;
    16. cout << func(2) << endl;
    17. cout << func(3) << endl;
    18. cout << func(4) << endl;
    19. cout << func(5) << endl;
    20. return 0;
    21. }

    结果

    5 x%y=x&(y-1)

    这个是在leveldb源码中看到的三行代码

    1. const int align = (sizeof(void*) > 8) ? sizeof(void*) : 8;
    2. static_assert((align & (align - 1)) == 0,
    3. "Pointer size should be a power of 2");
    4. size_t current_mod = reinterpret_cast<uintptr_t>(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博客

  • 相关阅读:
    手摸手 Spring Cloud Gateway + JWT 实现登录认证
    Prompt提示词工程构建指南
    利用yolov5进行目标检测,并将检测到的目标裁剪出来
    如何自己制作电子杂志
    C语言-字符串排序
    Python编程:创建图像浏览器应用程序
    python数学建模--模拟退火算法求解一元函数极值
    uniapp的h5项目怎样分享指定信息到Facebook
    2022年GPS广播星历精密星历如何下载
    postman和jmeter的区别何在?
  • 原文地址:https://blog.csdn.net/Zhouzi_heng/article/details/126212777