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

移位运算符:把整数的二进制位进行左移或右移 .左移一位,相当于这个数乘以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

	
	}
}