zoukankan      html  css  js  c++  java
  • 常用位运算规则

    1、描述

    • 计算机中所有的数据二进制的形式存储在设备中。即 0、1 两种状态,计算机对二进制数据进行的运算称为位运算,而我们看到的十进制数,则是计算机通过二进制运算之后转为了十进制转换的结果。
    • 下面代码示例中会在变量后面注释二进制形式,以Java的int类型计算,int类型长度为4字节,总共32位,第一位为符号位,1为负数,0为正数,如1的二进制即为0000 0000 0000 0000 0000 0000 0000 0001,-1则为1000 0000 0000 0000 0000 0000 0000 0001,为了方便演示,会取一些各位数为变量的值,所以中间的0省略,正数写成0...0001,负数写成1...0001。
    • 二级制运算中,是通过补码运算,正数的补码=反码=原码,负数的补码=原码取反 + 1,计算结果如果是符号位是0,则直接转换十进制,为1则先求补码,再转为十进制。负数参与计算一样。

    2、"&" 与运算(两个位都为1则为1)

    public static void example1() {
        int i1 = 1;   //0 ... 0001
        int i2 = 0;   //0 ... 0000
        int i3 = 1;   //0 ... 0001
        /**  二进制       十进制
         *  0 ... 0001     1        0 ... 0001      1
         *          &                       &
         *  0 ... 0000     0        0 ... 0001      1
         *  ___________________________________________________________
         *  0 ... 0000     0        0 ... 0001      1
         **/
        System.out.println("i1 & i2 =" + (i1 & i2));
        System.out.println("i1 & i3 =" + (i1 & i3));
    }
    //结果:
    i1 & i2 = 0
    i1 & i3 = 1

    3、"|" 或运算(一个为1则为1)

    public static void example1() {
        int i1 = 1;   //0 ... 0001
        int i2 = 0;   //0 ... 0000
        int i3 = 1;   //0 ... 0001
        /**  二进制       十进制
         *  0 ... 0001     1        0 ... 0001      1
         *          &                       &
         *  0 ... 0000     0        0 ... 0001      1
         *  ___________________________________________________________
         *  0 ... 0000     0        0 ... 0001      1
         **/
        System.out.println("i1 & i2 = " + (i1 & i2));
        System.out.println("i1 & i3 = " + (i1 & i3));
    }
    //结果:
    i1 | i2 = 1
    i1 | i3 = 1

    4、"^" 异或运算(两个不同则为1)

    public static void example3() {
        int i1 = 1;  //0001
        int i2 = 2;  //0010
        int i3 = 3;  //0011
        /**  二进制       十进制
         *  0 ... 0001     1        0 ... 0001      1
         *          &                       &
         *  0 ... 0010     2        0 ... 0011      3
         *  ___________________________________________________________
         *  0 ... 0011     3        0 ... 0010      2
         **/
        System.out.println("i1 ^ i2 =" + (i1 ^ i2));
        System.out.println("i1 ^ i3 =" + (i1 ^ i3));
    }
    //结果:
    i1 ^ i2 = 3
    i1 ^ i3 = 2

    5、"<<" 左移运算(右边补0,向左移动)

    public static void example5() {
        int i1 = 1;  //0001
        int i3 = 3;  //0011
        /**  二进制       十进制
         *  0 ... 0001     1         0 ... 0011      3      0 ... 0011      3      
         *         <<                       <<                      <<
         *  _____________________________________________________________________________________
         *  0 ... 0010     2         0 ... 0110      6      0 ... 1100      12
         **/
        System.out.println("i1 << 1 = " + (i1 << 1));
        System.out.println("i3 << 3 = " + (i3 << 1));
        System.out.println("i3 << 3 = " + (i3 << 2));
    }
    //结果:
    i1 << 1 = 2
    i3 << 3 = 6
    i3 << 3 = 12

    6、">>" 右移运算(正数,左边补0,向右移动;负数,左边补1,向右移动)

    public static void example8() {
        int i1 = 1;  //0001
        int i2 =-1;  //1... 0001
        int i3 = 3;  //0011
        /**  二进制       十进制
         *  0 ... 0001     1         1 ... 0001           -1      0 ... 0011      3
         *         >>                       >>                      >>
         *  _____________________________________________________________________________________
         *  0 ... 0000     0         1 1... 0000 (反码)   -1       0 ... 0000      0
         **/
        System.out.println("i1 >> 1 = " + (i1 >> 1));
        System.out.println("i2 >> 1 = " + (i2 >> 1));
        System.out.println("i3 >> 3 = " + (i3 >> 2));
    }
    //结果:
    i1 >> 1 = 0
    i2 >> 1 = -1
    i3 >> 3 = 0

    7、">>>"无符号右移(无视符号位,右移都补0)

    public static void example6() {
        int i1 = 1;
        int i2 = -2;
        /**  二进制       十进制
         *  0 ... 0001     1         1 ... 0010      -2      1 ... 0010      -2
         *        >>>                       >>>                     >>>
         *  _____________________________________________________________________________________
         *  0 ... 0000     0         0 1... 0000            0 11 ... 0000
         **/
        System.out.println("i1 >>> 1 =" + (i1 >>> 1));
        System.out.println("i2 >>> 1 =" + (i2 >>> 1));
        System.out.println("i2 >>> 2 =" + (i2 >>> 2));
    }
    //结果:
    i1 >>> 1 =0
    i2 >>> 1 =2147483647
    i2 >>> 2 =1073741823

    8、"~" 取反运算

    public static void example4() {
        int i1 = 1;  //0001 1110  1...0001 + 0001 =0010 = -2
        int i2 = 0;  //0000 1111  1...0000 + 0001 =0001 = -1
        /**  二进制       十进制
         *  0 ... 0001     1         0 ... 0000      0
         *          ~                        ~
         *  1 ... 1110               1 ... 1111
         *  1 ... 0001               1 ... 0000
         *          +                        +
         *  0 ... 0001               0 ... 0001
         *  ___________________________________________________________
         *  1 ... 0010    -2         1 ... 0001      -1
         **/
        System.out.println("~i1 = " + (~i1));
        System.out.println("~i2 = " + (~i2));
    }
    //结果:
    ~i1 = -2
    ~i2 = -1
  • 相关阅读:
    语言相关
    一道简单DP题
    一道概率题
    Android CrashHandler
    一道简单数学题
    面试中遇到的随机题目
    VMWare 无损扩展磁盘大小
    Android 源码编译记录
    Android handler 内存泄露分析及解决方法
    Android 反编译
  • 原文地址:https://www.cnblogs.com/zhexuejun/p/14914838.html
Copyright © 2011-2022 走看看