目录
位运算符除“按位与”和“按位或”运算符外,其他只能用于处理整数的操作数,包括byte、short、char、int和long等数据类型。位运算是完全针对位方面的操作。整型数据在内存中以二进制的形式表示,如int型变量7的二进制表示是000000000 00000000 00000000 00000111。
左边最高位是符号位,最高位是0表示正数,若为1表示负数。负数采用补码表示,如-8的二进制表示为111111111 1111111111 1111111 11111000。这样就可以对整型数据进行按位运算。
1.“按位与”运算
“按位与”运算的运算符位“&”,为双目运算符。“按位与”运算的运算法则是:如果两个整型数据a、b对应位都是1,则结果位才是1,否则位0。如果两个操作数的精度不同,则结果的精度与精度高的操作数相同。
2.“按位或”运算
“按位或”运算的运算符位“&”,为双目运算符,“按位或”运算的运算规则是:如果两个操作数对应位都是0,则结果位才是0,否则为1。如果两个操作数的精度不同,则结果的精度与精度高的操作数相同。
3.“按位取反”运算
“按位取反”运算也称“按位非”运算,运算符位“~”,为单目运算符。“按位取反”就是将操作数二进制中的1修改为0,0修改为1。
4.“按位异或”运算
“按位异或”运算的运算符是“^”,为双目运算符。“按位异或”运算的运算法则是:当两个操作数的二进制表示相同(同时位0或同时为1)时,结果为0,否则为1。若两个操作数的精度不同,则结果的精度与精度高的操作数相同。
5.移位操作
除了上述运算符,还可以对数据按二进制位进行移位操作。Java中的移位运算符有以下3种:
<<:左移
>>:右移
>>>:无符号右移
- 左移就是将运算符左边的操作数二进制数据,按照运算符右边操作数指定的位数向左移动,右边移空的部分补0。
- 右移则复杂一些。当使用“>>”符号时,如果最高位是0,右移动的位就填入0,;如果最高位是1,右移空的位就填入1。
右移
1 | 0 | 1 | 1 | 0 | 0 |
右移后补1 左边最高位是1因此补1,最右边0被抛弃
1 | 1 | 0 | 1 | 1 | 0 |
此外,Java还提供了无符号右移“>>>”,无论最高位是0还是1,左侧被移空的高位都填入0。
- 技巧:移位可以实现整数除以或乘以2n的效果。例如,y<<2与y*4的结果相同;y>>1的结果与y/2的结果相同。总之,一个数左移n位,就是将这个数乘以2n;一个数右移n位,就是将这个数除以2n。
//实例
public class BitTest {
public static void main(String[] args){
System.out.println("-----------------------左移位----------------------");
int i = 21;
i = 21;
System.out.println("i << 2 : " + (i << 2));
System.out.println("i << 3 : " + (i << 3 ));
System.out.println("i << 27 : " + (i << 27));
System.out.println("------与、或、异或(提示:逻辑运算符1当作true,0当作false。;计算的是底层2进制数据)------");
int m = 12;
int n = 5;
System.out.println("m & n : " + (m & n)); //底层二进制数据1和1的时候才是1true,1和0是false
System.out.println("m | n : " + (m | n)); //底层二进制位进行|运算,只有0 | 0时结果是0,否则是1
System.out.println("m ^ n : " + (m ^ n));
//相同二进制位进行^运算,结果是0;1^1=0,0^0=0。不相同二进制位 ^ 运算结果是1。1^0=1 , 0^1=1(二进制数据不相同的是1,相同的是0)
}
}
//编译输出(提示:负负得正)
-----------------------左移位----------------------
i << 2 : 84
i << 3 : 168
i << 27 : -1476395008
------与、或、异或(提示:逻辑运算符1当作true,0当作false;计算的是底层2进制数据)------
m & n : 4
m | n : 13
m ^ n : 9
Process finished with exit code 0
结论:
1.位运算符操作的都是整型数据;
二、三元运算符
//实例
package com.wkcto;
/*
1.三元运算符:
条件式 ? 值1 : 值2
三元运算符的运算规则为:若条件式的值为true,则整个表达式取值1,否则取值2。例如:
boolean b = 20 <45 ? true : false;
上述程序表达式”20<45“的运算结果返回真,那么boolean型变量b取值为true。相反,如果表达式的运算结果返回为假,则boolean型变量b取值为false。
三元运算符等价于if...else语句,例如上述代码等价于:
boolean a; //声明boolean型变量
if(20<45) //将20<45作为判断条件
a = true; //条件成立,将true赋值给a
else
a = false; //条件不成立,将false赋给a
*/
public class SanYuanTest {
public static void main(String[] args) {
//获取两个整数的最大值
int m = 12;
int n = 5;
int max = (m > n )? m : n; //表达式1和表达式2的数据类型要一致
System.out.println(max);
double num = (m > n) ? 2:1.0;
System.out.println(num);
System.out.println("-------------三元运算符可以嵌套------------------");
n = 12;
String maxstr = (m > n)? "m大" : ((m == n)? "m和n相等" : "n大");
System.out.println(maxstr);
System.out.println("----三元运算符可以嵌套--获取三个数的最大值--写法1-----");
int n1 = 12;
int n2 = 30;
int n3 = -43;
int max1 = (n1 > n2)? n1:n2;
int max2 = (max1 > n3)? max1:n3;
System.out.println("三个数中的最大值为:" + max2);
System.out.println("----三元运算符可以嵌套--获取三个数的最大值--写法2-----");
int max3 = (((n1 > n2)? n1 : n2) > n3)? ((n1 >n2)? n1 : n2) : n3;
System.out.println("三个数中的最大值为:" + max3);
System.out.println("----改写为if-else-----");
if (m > n){
System.out.println(m);
}else{
System.out.println(n);
}
}
}
//编译结果
12
2.0
-------------三元运算符可以嵌套------------------
m和n相等
----三元运算符可以嵌套--获取三个数的最大值--写法1-----
三个数中的最大值为:30
----三元运算符可以嵌套--获取三个数的最大值--写法2-----
三个数中的最大值为:30
----改写为if-else-----
12
Process finished with exit code 0
三、三元运算符与if-else转换
1.凡是可以使用三元运算符的地方,都可以改写为if-else
2.反之能写if-else的不一定能用运算符(通俗讲:if-else是一个比较大的流程控制语句结构可以很复杂,而三元运算符只是一个简单的运算符或表达式,它没有一个普遍适用性)
3.如果程序既可以使用三元运算符,又可以使用if-else流程控制结构,那么优先使用三元运算符。原因:简洁、执行效率高。
四、JAVA运算符的优先级
Java中的表达式就是使用运算符连接起来的复合Java规则的式子。运算符的优先级决定了表达式中运算执行的先后顺序。通常,优先级由高到低的顺序依次是:
-
增量和减量运算
-
算数运算
-
比较运算
-
逻辑运算
-
赋值运算
如果两个运算有相同的优先级,那么左边的表达式要比右边的表达式先被处理
优先级 | 描 述 | 运算符 |
---|---|---|
1 | 圆括号 | () |
2 | 正负号 | +、- |
3 | 一元运算符 | ++、--、! |
4 | 乘除 | *、/、% |
5 | 加减 | +、- |
6 | 移位运算 | >>、>>>、<< |
7 | 比较大小 | <、>、>=、<= |
8 | 比较是否相等 | ==、!= |
9 | 按位与运算 | & |
10 | 按位异或运算 | ^ |
11 | 按位或运算 | | |
12 | 逻辑与运算 | && |
13 | 逻辑或运算 | || |
14 | 三元运算符 | ?: |
15 | 赋值运算符 | = |
技巧:在编写程序时,尽量使用圆括号来指定运算次序,以免产生错误的运算顺序。
此外,只有单目运算符、三元运算符、赋值运算符是从右向左运算的。