一、与、或、异或、取反
Java位运算符是对操作数的二进制位进行运算,操作数和计算结果都是整型,位运算符如下:
&与:
两个二进制位只要有一个为0那么结果就为0,否则结果为1。
|或:
两个二进制位只要有一个为1那么结果就为1,否则结果为0。
^异或:
任何相同二进制位进行 ^ 运算,结果是0;不相同二进制位 ^ 运算结果是1。
~取反:
0变1,1变0
记的时候可以把1当作true,0当作flase
/**
* @Auther: allone_SilenceTXB
* @Date: 2022/1/15
* @Description:
*/
public class OperatorDemo1 {
public static void main(String[] args) {
/*与、或、异或、取反*/
//与 只要有0就是0 否则为1
System.out.println(3 & 4); //0
//或 只要有1就是1 否则为0
System.out.println(3 | 4); //7
//异或 相同为0 不同为1
System.out.println(3 ^ 4); //7
//取反 0变1 1变0(结果为补码要转成原码)
System.out.println(~3); //-4
}
}
二、左移、右移、无符号右移
1、左移
语法如下:
操作数<<位数
将符号左边的操作数左移指定的位数。
首先将左边的操作数转为二进制。
然后按照要求左移指定位数,左边最高位丢弃,右边补齐0。
比如:
3<<2
3的二进制:
00000000 00000000 00000000 00000011
左移2位,左边最高位丢弃,右边补齐0:
00000000 00000000 00000000 00001100
2、右移
语法如下:
操作数>>位数
将符号左边的操作数右移指定的位数。
首先将左边的操作数转为二进制。
然后按照要求右移指定位数,最高位是0,左边补齐0;最高为是1,左边补齐1。
比如:
24>>2
24的二进制:
00000000 00000000 00000000 00011000
右移2位,最高位是0,左边补齐0;最高为是1,左边补齐1:
00000000 00000000 00000000 00000110
3、无符号数右移
语法如下:
操作数>>>拉数
将符号左边的操作数右移指定的位数。
首先将左边的操作数转为二进制。
然后按照要求右移指定位数,无论最高位是0还是1左边补齐0。
运行下边的程序:
//<< 左移1位即左边数乘以2的1次方,左移2位即左边数乘以2的2次方,以此类推
System.out.println(3 << 2);
//>> 右移1位即左边数除以2的1次方,右移2位即左边数除以2的2次方,以此类推
System.out.println(24 >> 2);
//负数转成二进制要用补码,最终将补码右移,再转成原码
System.out.println(-24 >> 2);
//无符号数右移无论最高位是0还是1左边都补齐0
System.out.println(24 >>> 2);
System.out.println(-24 >>> 2);
三、奇偶判断
位运算是直接操作二进制位,效率较高,一些算法会采用位运算。
奇偶判断是判断一个是奇数还是偶数,如何使用位运算实现呢?
使用与(&)运算可以实现,根据与运算的特点,两个二进制位只要有一个为0那么结果就为0,否则结果为1。
二进制的最低位为1一定是奇数,为0则一定是偶数,我们让该数和1进行与运算,结果为1则是奇数,为0则是偶数。
程序如下:
int a = 1;
int x = 6;
int y = 7;
//和1与运算,结果为1则为奇数
System.out.println(x & a);
//和1与运算,结果为0则为偶数
System.out.println(y & a);
四、两数交换
/**
* 位运算实现两数交换 效率高 直接操作内存
*/
private static void swap3() {
int m = 5;
int n = 10;
m = m ^ n;
n = m ^ n; //此时 n = m ^ n ^ n
m = m ^ n; //此时 m = m ^ n ^ m
System.out.println(m); //10
System.out.println(n); //5
}