6. 移位运算符
移位运算符有三个: << >> >>> ,都是二元运算符,且都是按照二进制比特位来运算的。
**1. 左移 <<:最左侧位不要了,最右侧补 0 **
例如:
int a = 0x10; System.out.printf("%x\n", a << 1); // 运行结果按十六进制打印
图解:
运行结果:
向左移位时,丢弃的是符号位,因此正数左移可能会编程负数
2. 右移 >>:最右侧位不要了,最左侧补符号位(正数补 0,负数补 1)
例如:
int a = 0x10; System.out.printf("%x\n", a >> 1); // 运行结果按十六进制打印
图解:
运行结果:
3. 无符号右移 >>>:最右侧位不要了,最左侧补 0
int a = 0xffffffff; System.out.printf("%x\n", a >>> 1);
运行结果:
注:
- 左移 1 位,相当于原数字 * 2. 左移 N 位,相当于原数字 * 2 的N次方
- 右移 1 位,相当于原数字 / 2. 右移 N 位,相当于原数字 / 2 的N次方
- 由于计算机计算移位效率高于计算乘除,当某个代码正好乘除 2 的N次方的时候可以用移位运算代替
- 移动负数位或者移位位数过大都没有意义
7. 条件运算符
条件运算符只有一个:
表达式1 ? 表达式2 : 表达式3
- 当 表达式1 的值为 true 时,整个表达式的值为 表达式2 的值
- 当 表达式1 的值为 false 时,整个表达式的值为 表达式3 的值
- 也是 Java 中唯一的一个 三目运算符,是条件判断语句的简化写法
例如:求两个整数的最大值
int a = 10; int b = 20; int max = a > b ? a : b; System.out.println(max);
运行结果:
注:
- 表达式2和表达式3的结果要是同类型的,除非能发生类型隐式类型转换
- 表达式不能单独存在,其产生的结果必须要被使用
int a = 10; int b = 20; a > b? a : b; // 报错:Error:(15, 14) java: 不是语句
8. 运算符的优先级
在一条表达式中,各个运算符可以混合起来进行运算,但是运算符的优先级不同,比如:* 和 / 的优先级要高于 +和 - 。
观察下段代码是否正确:
// 求a和b的平均值 int a = 10; int b = 20; int c = a + (b - a) >> 1;//右移一位相当于 /2 System.out.println(c);
运行结果:
为什么结果和我们想的不一样?
这是因为在上述表达式中,由于 + 的优先级要高于 >> ,因此 a 先和 b-a 的结果做加法,整体为20,最后再进行右移,因此结果为 10 。
为了不被优先级干扰,我们可以在恰当的位置加上括号:
int a = 10; int b = 20; int c = a +( (b - a) >> 1 );//右移一位相当于 /2 System.out.println(c);
运行结果: