移位运算符和位运算符本质上都是操作二进制位,因为计算机存储的是二进制数据,运算效率相对较高。
移位运算符:把整数的二进制位进行左移或右移 .左移一位,相当于这个数乘以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
}
}