5.位运算符
位运算符,见名知意 就可以知道是处理二进制位的运算符。
补充知识:
Java 中数据存储的最小单位是字节,而数据操作的最小单位是比特位
1 字节 = 8 比特位
位操作表示 按二进制位运算. 计算机中都是使用二进制来表示数据的(二进制:01构成的序列), 按位运算就是在按照 二进制位 的每一位依次进行运算。
位运算符:& | ~ ^
&:按位与
| :按位或
~:按位取反
^:按位异或
注:位运算符操作数可以是变量也可以是常量
5.1 按位与 &
&:全一得一,两个比特位都是 1 ,则为 1
public class Test { public static void main(String[] args) { int a = 10; int b = 20; System.out.println(a & b); System.out.println(7 & 6); } }
上述代码运行结果:
代码分析:
a = 10,b = 20,然后 a & b。 首先将 a 和 b 都转换成二进制的形式,因为 a,b 是 int 类型所以转换为 32 位二进制位:
a:00000000 00000000 00000000 00001010
b:00000000 00000000 00000000 00010100
然后进行按位与,全一得一,则结果为:
00000000 00000000 00000000 00000000,结果就为 0
7 & 6, 7 和 6 默认都是 int 类型的,首先将 7 和 6 都转换为 32 位二进制位:
7:00000000 00000000 00000000 00000111
6:00000000 00000000 00000000 00000110
然后进行按位与,全一得一,则结果为:
00000000 00000000 00000000 00000110 ,就为 6
5.2 按位或 |
| :见一得一,两个比特位只要有一个是 1 ,则为 1
public class Test { public static void main(String[] args) { int a = 10; int b = 20; System.out.println(a | b); System.out.println(7 | 6); } }
上述代码运行结果:
代码解析:
a = 10,b = 20,然后 a | b。 首先将 a 和 b 都转换成二进制的形式,因为 a,b 是 int 类型所以转换为 32 位二进制位:
a:00000000 00000000 00000000 00001010
b:00000000 00000000 00000000 00010100
然后进行按位与,见一得一,则结果为:
00000000 00000000 00000000 00011110,结果就为 30
7 & 6, 7 和 6 默认都是 int 类型的,首先将 7 和 6 都转换为 32 位二进制位:
7:00000000 00000000 00000000 00000111
6:00000000 00000000 00000000 00000110
然后进行按位与,见一得一,则结果为:
00000000 00000000 00000000 00000111 ,就为 7
5.3 按位取反 ~
~ : 1 变 0 , 0 变1
public class Test { public static void main(String[] args) { int a = 10; System.out.println(~a); } }
上述代码运行结果:
代码解析:
a = 10,然后 ~a 。 首先将 a 转换成二进制的形式,因为 a 是 int 类型所以转换为 32 位二进制位:
a:00000000 00000000 00000000 00001010
然后按位取反得,1 变 0 , 0 变 1,得:
11111111 11111111 11111111 11110101
计算机只会存储二进制补码的形式,所以计算机会认为这是补码,在用户进行读取的时候计算机会自动将补码转换成原码,然后进行读取出来
补码转原码有两种方法
方法一:补码除了符号位,其他位按位取反,然后加1,的原码
方法二:补码减一得反码,反码符号位不变其他位按位取反得原码
则 ~a 的结果就是 -11
补充知识:
正数的原 反 补相同
负数的反码等于原码符号位不变,然后按位取反;负数的补码就是负数的反码加1
5.4 按位异或 ^
^ :相同为 0,不同为 1
public class Test { public static void main(String[] args) { int a = 10; int b = 20; System.out.println(a ^ b); } }
上述代码运行结果 :
代码解析:
a = 10,b = 20,然后 a ^ b。 首先将 a 和 b 都转换成二进制的形式,因为 a,b 是 int 类型所以转换为 32 位二进制位:
a:00000000 00000000 00000000 00001010
b:00000000 00000000 00000000 00010100
然后进行按位异或,相同为 0,不同为 1 则结果为:
00000000 00000000 00000000 00011110,结果就为 30
6.移位运算
移位运算符,见名知意 肯定又是对二进制位的运算
移位运算符:<< >> >>>
<<:左移
>>:右移
>>>:无符号右移
6.1 左移 <<
<< :最左侧位不要了, 最右侧补 0
public class Test { public static void main(String[] args) { int a = 10; System.out.println(a << 1); } }
上述代码运行结果:
代码解析:
a = 10,然后 a << 1 。 首先将 a 转换成二进制的形式,因为 a 是 int 类型所以转换为 32 位二进制位:
a:00000000 00000000 00000000 00001010
然后最左侧位不要了, 最右侧补 0
00000000 00000000 00000000 00010100
将二进制位转换为十进制就是 20
注:
向左移位时,丢弃的是符号位,因此正数左移可能会变成负数
左移 1 位, 相当于原数字 * 2. 左移 N 位, 相当于原数字 * 2 的N次方.
5.2 右移 >>
>>:最右侧位不要了, 最左侧补符号位(正数补0, 负数补1)
public class Test { public static void main(String[] args) { int a = 10; System.out.println(a >> 1); } }
上述代码运行结果:
代码解析:
a = 10,然后 a >> 1 。 首先将 a 转换成二进制的形式,因为 a 是 int 类型所以转换为 32 位二进制位:
a:00000000 00000000 00000000 00001010
然后最右边侧位不要了, 左边正数补0, 负数补1
00000000 00000000 00000000 00001010
将二进制位转换为十进制就是 20
注:右移 1 位, 相当于原数字 / 2. 右移 N 位, 相当于原数字 / 2 的N次方.
5.3 无符号右移 >>>
>>>:最右侧位不要了, 最左侧补 0
public class Test { public static void main(String[] args) { int a = -10; System.out.println(a >>> 1); } }
上述代码运行结果:
代码解析:
a = -10,然后 a >>> 1 。 首先将 a 转换成二进制的形式,因为 a 是 int 类型所以转换为 32 位二进制位:
a:10000000 00000000 00000000 00001010
如果是负数,则需要转为补码然后存储在计算机内进行运算
原码:10000000 00000000 00000000 00001010
反码:11111111 11111111 11111111 11110101
补码:11111111 11111111 11111111 11110110
然后无符号左移: 01111111 11111111 11111111 11111011
结果就为:2147483643
6.条件运算符
条件运算符只要一个:?:
条件运算符的格式:表达式1 ? 表达式2 : 表达式3
表达式1 的结果必须是 boolean 类型
当 表达式1 的值为 true 时, 整个表达式的值为 表达式2 的值; 当 表达式1 的值为 false 时, 整个表达式的值为 表达式3 的值.
条件运算符也是 Java 中唯一的一个 三目运算符, 是条件判断语句的简化写法.
public class Test { public static void main(String[] args) { int a = 10; int b = 20; int c = (a > b) ? a : b; System.out.println(c); } }
上述代码运行结果:
代码解析:
如果 a > b 为 true ,则把 a 的值赋值给 c,如果 a > b 为 false ,则把 b 的值赋值给 c