zoukankan      html  css  js  c++  java
  • 【算法】位运算与优化

    刚刚学算法的时候,看到dalao处处用位运算,感觉真的太玄学了,然后直到今天才深入理解了下位运算的操作,其实并没有多么玄学,只不过是利用了计算机本身的性质罢了。

    基本概念:

    真值:

    带符号位的机器数对应的真正数值称为机器数的真值
    0000 0001的真值 = +000 0001 = +1,1000 0001的真值 = –000 0001 = –1

    原码:

    原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值
    PS:正数的原、反、补码都一样:0的原码跟反码都有两个,因为这里0被分为+0和-0。

    反码:

    正数的反码是其本身
    负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.
    [+1] = [00000001]原 = [00000001]反
    [-1] = [10000001]原 = [11111110]反

    补码:

    正数的补码就是其本身

    负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

    [+1] = [00000001]原 = [00000001]反 = [00000001]补
    [-1] = [10000001]原 = [11111110]反 = [11111111]补

    PS:0的补码是唯一的,如果机器字长为8那么[0]补=00000000。

    移码:

    移码最简单了,不管正负数,只要将其补码的符号位取反即可。

    例如:X=-101011 , [X]原= 10101011 ,[X]反=11010100,[X]补=11010101,[X]移=01010101

    位运算基本运算符:

    &:按位与
    |:按位或
    ^:按位异或(相同为1,不同为0)
    ~:取反
    <<:左移
    >>:右移

    常用位运算优化方法:

    1.判断整数奇(1)偶(0)性:

    bool IsOdd(int x)//判断是否为奇数
    {
        return x&1;
    }

    2.乘以或除以2的幂:

    列如:    乘以2: x<<1;
         乘以2的n次方:x<<n;
         除以2:x>>2;
         除以2的n次方:x>>n;
    变式:    计算2的n次方:2<<(n-1);

    3.比较两个数是否相等:

    计算两个数的异或值,若等于0,则两数相等。

    bool IsEqual(int a,int b)
    {
        return !(a^b);
    }

    4.不使用第三方变量交换a,b:

    int a,int b;
    a=a^b; b=a^b; a=a^b;

    5.判断两个数是否同号:

    !((a^b)>>31);

    6.求n的绝对值:

    (n^(n>>31))-(n>>31);

    7.提取lowbit():

    int lowbit(int x)
    {
        return x&-x;
    }

    8.计算整数x和y的平均值,可防止溢出。

    int average(int x, int y) //返回X,Y 的平均值 
    { 
      return (x&y)+((x^y)>>1); 
    }

    9.判断一个整数n是否为2的幂 2^n:

    ((x&(x-1))==0)&&(x!=0);
  • 相关阅读:
    Redis入门--- 五大数据类型 ---String ,List
    Redis入门 --- 安装
    Netty 应用实例-群聊系统,心跳检测机制案例 ,WebSocket 编程实现服务器和客户端长连接
    红锁的实现
    基于Redis实现分布式锁
    基于分布式锁 分布式全局唯一ID
    Netty Java BIO 编程 (一)
    Netty Java NIO 基本介绍Channel 和 buffer (二)
    Java AIO 基本介绍
    SpringBoot 系列教程自动配置选择生效
  • 原文地址:https://www.cnblogs.com/virtualman/p/9483612.html
Copyright © 2011-2022 走看看