Java-Java中的运算符
修订记录 | 版本 | 是否发布 |
---|---|---|
2020-09-23 | v1.0 | 是 |
一、Java &、&&、|、||、^、<<、>>、~、>>>等运算符
*Java运算符大致分为逻辑运算符(&&,||,!)、算数运算符(+, -, , / ,+=)、位运算符(^,|,&)、其他运算符(三元运算符)
&(按位与)
![image-20200923160517009](https://gitee.com/lrkkevin/oss/raw/master/uPic/2020/09/23/image-20200923160517009.png)
位运算符
&按位与的运算规则是将两边的数转换为二进制位,然后运算最终值,运算规则即(两个为真才为真)1&1=1 , 1&0=0 , 0&1=0 , 0&0=0
3的二进制位是0000 0011 , 5的二进制位是0000 0101 , 那么就是011 & 101,由按位与运算规则得知,001 & 101等于0000 0001,最终值为1
7的二进制位是0000 0111,那就是111 & 101等于101,也就是0000 0101,故值为5
&&(逻辑与)
![image-20200923160619722](https://gitee.com/lrkkevin/oss/raw/master/uPic/2020/09/23/image-20200923160619722.png)
逻辑运算符
&&逻辑与也称为短路逻辑与,先运算&&左边的表达式,一旦为假,后续不管多少表达式,均不再计算,一个为真,再计算右边的表达式,两个为真才为真。
|(按位或)
![image-20200923160700528](https://gitee.com/lrkkevin/oss/raw/master/uPic/2020/09/23/image-20200923160700528.png)
位运算符
|按位或和&按位与计算方式都是转换二进制再计算,不同的是运算规则(一个为真即为真)1|0 = 1 , 1|1 = 1 , 0|0 = 0 , 0|1 = 1
6的二进制位0000 0110 , 2的二进制位0000 0010 , 110|010为110,最终值0000 0110,故6|2等于6
||(逻辑或)
![image-20200923160740523](https://gitee.com/lrkkevin/oss/raw/master/uPic/2020/09/23/image-20200923160740523.png)
逻辑运算符
逻辑或||的运算规则是一个为真即为真,后续不再计算,一个为假再计算右边的表达式。
^(异或运算符)
![image-20200923160818245](https://gitee.com/lrkkevin/oss/raw/master/uPic/2020/09/23/image-20200923160818245.png)
位运算符
^异或运算符顾名思义,异就是不同,其运算规则为1^0 = 1 , 1^1 = 0 , 0^1 = 1 , 0^0 = 0
5的二进制位是0000 0101 , 9的二进制位是0000 1001,也就是0101 ^ 1001,结果为1100 , 00001100的十进制位是12
<<(左移运算符)
![image-20200923160859822](https://gitee.com/lrkkevin/oss/raw/master/uPic/2020/09/23/image-20200923160859822.png)
位运算符
5<<2的意思为5的二进制位往左挪两位,右边补0,5的二进制位是0000 0101 , 就是把有效值101往左挪两位就是0001 0100 ,正数左边第一位补0,负数补1,等于乘于2的n次方,十进制位是20
>>(右移运算符)
![image-20200923160932344](https://gitee.com/lrkkevin/oss/raw/master/uPic/2020/09/23/image-20200923160932344.png)
位运算符
凡位运算符都是把值先转换成二进制再进行后续的处理,5的二进制位是0000 0101,右移两位就是把101左移后为0000 0001,正数左边第一位补0,负数补1,等于除于2的n次方,结果为1
~(取反运算符)
![image-20200923161018178](https://gitee.com/lrkkevin/oss/raw/master/uPic/2020/09/23/image-20200923161018178.png)
位运算符
取反就是1为0,0为1,5的二进制位是0000 0101,取反后为1111 1010,值为-6
>>>(无符号右移运算符)
![image-20200923161229280](https://gitee.com/lrkkevin/oss/raw/master/uPic/2020/09/23/image-20200923161229280.png)
正数无符号右移
无符号右移运算符和右移运算符的主要区别在于负数的计算,因为无符号右移是高位补0,移多少位补多少个0。
15的二进制位是0000 1111 , 右移2位0000 0011,结果为3
![image-20200923161303434](https://gitee.com/lrkkevin/oss/raw/master/uPic/2020/09/23/image-20200923161303434.png)
负数无符号右移
-6的二进制是6的二进制取反再加1,6的二进制也就是0000 0000 0000 0000 0000 0000 0000 0110,取反后加1为1111 1111 1111 1111 1111 1111 1111 1010,右移三位0001 1111 1111 1111 1111 1111 1111 1111
二、图解 Java 位运算
1. 原码、反码、补码的转换
(1) 正数的原码、反码、补码相同
![image-20200923162020156](https://gitee.com/lrkkevin/oss/raw/master/uPic/2020/09/23/image-20200923162020156.png)
(2) 负数的原码、反码、补码转换如下图所示
![image-20200923162036559](https://gitee.com/lrkkevin/oss/raw/master/uPic/2020/09/23/image-20200923162036559.png)
需要说明的是,在计算机中,数字是以补码的形式存在的,计算也是用补码来进行计算,计算后的结果也是补码
2. 位运算
(1) & : 按位与
5 & 9 = 1
![image-20200923162100064](https://gitee.com/lrkkevin/oss/raw/master/uPic/2020/09/23/image-20200923162100064.png)
(2) | : 按位或
![image-20200923162117111](https://gitee.com/lrkkevin/oss/raw/master/uPic/2020/09/23/image-20200923162117111.png)
(3) ^ : 按位异或
5 ^ 9 = 12
![image-20200923162134629](https://gitee.com/lrkkevin/oss/raw/master/uPic/2020/09/23/image-20200923162134629.png)
(4) ~ : 按位非
~5 = -6
![image-20200923162155091](https://gitee.com/lrkkevin/oss/raw/master/uPic/2020/09/23/image-20200923162155091.png)
(5) << : 左移
5 << 2 = 20
![image-20200923162210304](https://gitee.com/lrkkevin/oss/raw/master/uPic/2020/09/23/image-20200923162210304.png)
-5 << 2 = -20
![image-20200923162224505](https://gitee.com/lrkkevin/oss/raw/master/uPic/2020/09/23/image-20200923162224505.png)
(6) >> : 右移
-5 >> 2 = -2
![image-20200923162240874](https://gitee.com/lrkkevin/oss/raw/master/uPic/2020/09/23/image-20200923162240874.png)
(7) >>> : 无符号右移
-5 >>> 2 = 1073741822
![image-20200923162258861](https://gitee.com/lrkkevin/oss/raw/master/uPic/2020/09/23/image-20200923162258861.png)
3. 注意
- 对于低于 int 类型(如byte、short和char)的操作数总是先自动转换为int类型后再移位
- 对于 int 类型的整数移位 a >> b, 当 b>32 时,系统先用 b 对 32 求余(因为 int 是 32 位),得到的结果才是真正移位的位数,例如,a >> 33 和 a >> 1 的结果相同,而 a >> 32 = a
- 对于 long 类型的整数移位 a >> b, 当 b>64 时,系统先用 b 对 64 求余(因为 long 是 64 位),得到的结果才是真正移位的位数
- 当进行移位运算时,只要被移位的二进制码没有发生有效位的数字丢失(对于正数而言,通常指被移出去的位全部是 0),不难发现左移 n 位就相当于乘以 2 的 n 次方,右移 n 位则是除以 2 的 n 次方
- 进行移位运算不会改变操作数本身,只是得到了一个新的运算结果