java 简单认识移位运算符和位运算符

移位运算符和位运算符本质上都是操作二进制位,因为计算机存储的是二进制数据,运算效率相对较高。

移位运算符:把整数的二进制位进行左移或右移 .左移一位,相当于这个数乘以2, 右移一位,相当于这个数除以2

/*
移位运算符
    把整数的二进制位进行左移或右移
    按位左移 <<    , 右侧补0,
    按位右移 >>,  左侧补符号位(最高位)
    无符号按位右移>>>,  左侧补0
*/
class Demo07 {
    public static void main(String[] args)     {
        int xx = 20;
        System.out.println( xx << 1 );        //40
        /* x在内存中的二进制形式为:
            0000 0000 0000 0000 0000 0000 0001 0100
            xx<<1 左移一位
          0 0000 0000 0000 0000 0000 0000 0010 1000         
        */

        System.out.println( xx >> 1 );        //10
        /* x在内存中的二进制形式为:
            0000 0000 0000 0000 0000 0000 0001 0100
            xx>>1 右移一位, 左侧补0
            0000 0000 0000 0000 0000 0000 0000 1010 0        
        */

        xx = -20;
        System.out.println( xx << 1 );        //-40
        /* x在内存中的二进制形式为:
            1111 1111 1111 1111 1111 1111 1110 1100
            xx<<1 左移一位
          1 1111 1111 1111 1111 1111 1111 1101 1000        
        */
        System.out.println( xx >> 1 );        //-10
        /* x在内存中的二进制形式为:
            1111 1111 1111 1111 1111 1111 1110 1100
            xx>>1 右移一位, 左侧补1
            1111 1111 1111 1111 1111 1111 1111 0110        
        */

        //左移一位,相当于这个数乘以2, 右移一位,相当于这个数除以2

        xx = -11;
        System.out.println( xx << 1 );        //-22
        /* x在内存中的二进制形式为:
            1111 1111 1111 1111 1111 1111 1111 0101
            xx<<1 左移一位
          1 1111 1111 1111 1111 1111 1111 1110 1010        
        */

        xx = -13;
        System.out.println( xx << 1 );        //-26
        /* x在内存中的二进制形式为:
            1111 1111 1111 1111 1111 1111 1111 0011
            xx<<1 左移一位, 右侧补0 
          1 1111 1111 1111 1111 1111 1111 1110 0110        
        */

        xx = -11;
        System.out.println( xx >> 1 );        //-6
        /* x在内存中的二进制形式为:
            1111 1111 1111 1111 1111 1111 1111 0101
            xx>>1 右移一位, 左侧补1
            1111 1111 1111 1111 1111 1111 1111 1010 1        
        */

        xx = -13;
        System.out.println( xx >> 1 );        //-7
        /* x在内存中的二进制形式为:
            1111 1111 1111 1111 1111 1111 1111 0011
            xx>>1 右移一位, 左侧补1
            1111 1111 1111 1111 1111 1111 1111 1001 1        
        */

        xx = -11;
        System.out.println( xx >>> 1 );        //2147483642
        /* x在内存中的二进制形式为:
            1111 1111 1111 1111 1111 1111 1111 0101
            xx>>>1 无符号移一位
            0111 1111 1111 1111 1111 1111 1111 1010 1        
        */

        //一个整数乘以/除以2的幂次方时,通过移位运算效率最高
    }
}

位运算符:

  按位与 & 按位或 | 按位异或 ^

/*
位运算符
        按位与&, 按位或|, 按位异或^, 按位取反
        
        &操作符左右两侧如果是布尔值, &就是逻辑与;
        左右两侧为整数,就是按位与
*/
class Demo08 {
        public static void main(String[] args)  {
                int x = 10;
                int y = 20;
                /*按位与
                        x在计算机中存储的01序列为:
                                0000 0000 0000 0000 0000 0000 0000 1010
                        y的二进制形式为:
                                0000 0000 0000 0000 0000 0000 0001 0100
                按位与&
                        ----------------------------------------------
                                0000 0000 0000 0000 0000 0000 0000 0000
                */
                System.out.println( x&y );                  //0

                /*按位或
                        x在计算机中存储的01序列为:
                                0000 0000 0000 0000 0000 0000 0000 1010
                        y的二进制形式为:
                                0000 0000 0000 0000 0000 0000 0001 0100
                按位或|
                        ----------------------------------------------
                                0000 0000 0000 0000 0000 0000 0001 1110
                */
                System.out.println( x|y );                      //30

                /*按位异或
                        x在计算机中存储的01序列为:
                                0000 0000 0000 0000 0000 0000 0000 1010
                        y的二进制形式为:
                                0000 0000 0000 0000 0000 0000 0001 0100
                按位异或^
                        ----------------------------------------------
                                0000 0000 0000 0000 0000 0000 0001 1110
                */
                System.out.println( x^y );                      //30

                /*按位取反
                        x在计算机中存储的01序列为:
                                0000 0000 0000 0000 0000 0000 0000 1010                 
                按位取反
                        ----------------------------------------------
                                1111 1111 1111 1111 1111 1111 1111 0101
                */
                System.out.println( ~x );                       //-11

                // 如何实现两个数的原地交换,  不借助于第三个变量,实现两个变量的交换
                x = 10;
                y = 20;
                //正常情况下,交换两个变量的值
                int t = x;
                x = y; 
                y = t;

                //方法1:
                x = 10;
                y = 20;
                x = x + y;              //x==30
                y = x - y;              //y==10
                x = x - y;              //x==20

                //方法2:
                x = 10;
                y = 20;
                x = x ^ y;              //x==30
                y = x ^ y;              //y==10
                x = x ^ y;              //x==20

        
        }
}