zoukankan      html  css  js  c++  java
  • C++中位运算

    简介

    1 位逻辑运算符:

          & (位   “与”)  and ----------------- 2个都为1 才是1-----------0^0 = 0 , 0^1 = 0,  1^0 = 0  1^1= 1 
          ^  (位   “异或”) ---------------------相同为0,不同为1--------0^0 = 0 , 1^1 = 0,  1^0 = 1  1^0 = 1 
          |   (位    “或”)   or------------------有一个是1 就是1 -------------0^0 = 0 , 0^1 = 1,  1^0 = 1  1^1 = 1 
          ~  (位   “取反”)
    2 移位运算符:
          <<(左移)

          >>(右移)

    优先级

     &    》 ^  》

    应用:

    1、&运算

    &运算通常用于二进制取位操作,例如一个数 &1的结果就是取二进制的最末位。

    这可以用来判断一个整数的奇偶,二进制的最末位为0表示该数是偶数,最末位为1表示该数为奇数

    2、| 运算

    | 运算通常用于二进制特定位上的无条件赋值,例如一个数|1的结果就是把二进制最末位强行变为1

    如果需要把二进制最末位变成0,对这个数 |1之后再减一就可以了,其实际意义就是把这个数强行变成最近接的偶数

    3、^运算

    leetcde:

    ^运算通常用于对二进制的特定一位进行取反操作,^运算的逆运算是它本身,也就是说两次异或同一个数最后结果不变,即(a^b)^b=a;

    ^运算可以用于简单的加密,比如原始值int a = 19880516;密钥 int key =1314520; 进行加密 int data=key^a = 20665500;解密 data^key == a;

    ^运算还可以实现两个值的交换而不需要中间变量,例如:

    先看加减法中交换实现

    void swap(long int &a,long int &b)

    {

         a = a+b;

         b = a-b;

         a = a-b;

    }

    void swap(long int &a,long int &b)

    {

        a = a^b;

        b = a^b;

        a = a^b;

    }

    所以 ^运算可以理解成类似加法(+)记忆 , 1+1 =0,1+0 =1,0+1 =1;0+0 =0;//因为机器码是二进制,1+1=2%2 =0,其实不然

    ~运算的定义把内存中的0和1全部取反,所以~运算时要格外小心,你需要注意整数类型有没符号,如果~的对象是无符号整数(不能表示负数),

    那么他的值就是它与它的上界限的之差,因为无符号类型的数是用00000000到FFFF依次表示的。

    位运算技巧:


    1. 如果乘上一个2的倍数数值,可以改用左移运算(Left Shift) 加速 300%

    x = x * 2;
    x = x * 64;
    //改为:
    x = x << 1; // 2 = 21
    x = x << 6; // 64 = 26

    2. 如果除上一个 2 的倍数数值,可以改用右移运算加速 350%

    x = x / 2;
    x = x / 64;
    //改为:

    x = x >> 1;// 2 = 21
    x = x >> 6;// 64 = 26

    3. 数值转整数加速 10%

    x = int(1.232)
    //改为:

    x = 1.232 >> 0;

    4. 交换两个数值(swap),使用 XOR 可以加速20%

    var t:int = a;
    a = b;
    b = t;
    //equals:
    a = a^b;
    b = a^b;
    a = a^b;

    5. 正负号转换,可以加入 300%

    i = -i;
    //改为
    i = ~i + 1; // NOT 写法
    //或
    i = (i ^ -1) + 1; // XOR 写法

    6. 取余数,如果除数为 2 的倍数,可利用 AND 运算加速 600%

    x = 131 % 4;
    //equals:
    x = 131 & (4 - 1);

    7. 利用 AND 运算检查整数是否为 2 的倍数,可以加速 600%

    isEven = (i % 2) == 0;
    //equals:
    isEven = (i & 1) == 0;

    8. 加速 Math.abs 600% 的写法1,写法2 又比写法1加速 20%

    //写法1
    i = x < 0 ? -x : x;

    //写法2

    i = (x ^ (x >> 31)) - (x >> 31);

    //写法3

    i=x^(~(x>>31)+1)+(x>>31);

    9. 比较两数值相乘之后是否拥有相同的符号,加速 35%

    eqSign = a * b > 0;
    //equals:
    eqSign = a ^ b > 0;

    其它位运算技巧
    1. RGB 色彩分离

    var 24bitColor:uint = 0xff00cc;
    var r:uint = 24bitColor >> 16;
    var g:uint = 24bitColor >> 8 & 0xFF;
    var b:uint = 24bitColor & 0xFF;

    2. RGB 色彩合并

    var r:uint = 0xff;
    var g:uint = 0x00;
    var b:uint = 0xcc;
    var 24bitColor:uint = r << 16 | g << 8 | b;

    参考:https://blog.csdn.net/a1351937368/article/details/77746574/

    参考:https://www.cnblogs.com/GlassHour/p/5522033.html

  • 相关阅读:
    操作系统开发系列—13.g.操作系统的系统调用 ●
    操作系统开发系列—13.f.Minix的中断处理(暂时忽略)
    操作系统开发系列—13.e.三进程
    操作系统开发系列—13.d.多进程 ●
    操作系统开发系列—解释typedef void (*int_handler) ();
    操作系统开发系列—13.c.进程之中断重入
    操作系统开发系列—13.b.进程之丰富中断处理程序
    操作系统开发系列—13.a.进程 ●
    操作系统开发系列—12.g.在内核中设置键盘中断
    操作系统开发系列—12.f.在内核中添加中断处理 ●
  • 原文地址:https://www.cnblogs.com/zle1992/p/10277253.html
Copyright © 2011-2022 走看看