位运算整理

名称 符号 例子 推理公式 运用场景
右移 >> 5>>2=1
-5>>2=-2
非负数右移2位为除以4
负数右移两位为正数除以4余数为0,则值就为该值的负数,否则为该值+1的负数
非负数的除法运算,运算效率比除运算效率高
无符号右移 >>> 5>>>2=1
-5>>>2=2^30-2
非负数和右移运算结果一致,负数为2^(32-右移位数)-(负数右移的结果) 待确认
左移 << 5<<2=20
-5<<2=-20
左移为乘以4 替换乘法运算
按位与 & 0&0=0;0&1=0;1&1=1 按位&运算 判断奇偶性(&1)
按位或 0 0=0;0
按位异或 ^ 0^0=0;0^1=1;1^1=0 按位^运算 a,b交换值不需要用临时变量
按位取反 ~ 0=-1;1=-2;~-1=0 ~n=-(n+1) 如果为该公式时,可以用n取反代替

运用场景:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#1.a取绝对值
(a^(a>>31))-(a>>31)
a >> 31 == 0 ? a : (~a + 1)
#2.m*2^n替换
m<<n
#3.判断奇偶性
a&1==1?"奇数":"偶数"
#4.不用零时变量交换两个数
a=m;
b=n;
a=a^b;
b=a^b;
a=a^b;
#5.取余数
a=m%16;
a=m&15;
#5.开关判断的使用场景
public interface UserOptType{
   long BASE_INFO = 1;
   long VIP_INFO = 1 << 1;
   long FANS_INFO = 1 << 2;
   long ATTENTION_INFO = 1 << 3;
   long MODEL_INFO = 1 << 4;
   long REAL_NAME_INFO = 1 << 5;
}


public class UserService{
    public Object getUserInfo(String userId,long optType){
     Object result = new Object();
        if ( optType & UserOptType.BASE_INFO > 0 ){
            setBaseInfo(userId,result);
        }
        if ( optType & UserOptType.VIP_INFO > 0 ){
            setVipInfo(userId,result);
}
// ......
    }
}

运行的实例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package pers.xiaotian.binary;

public class Cal {

public static void main(String[] args) {
//按位与&、按位或|、按位非~、按位异或^、右移>>、左移<<、无符号右移>>>
//数值的二进制存储方式,整数为源码,负数为补码(源码取反+1为补码)
System.out.println(-5>>>2);
System.out.println(3>>2);//3/2/2 =0
System.out.println(-18>>2);
System.out.println(-17>>2);
//-13的补码为:11111111 11111111 11111111 11101100
System.out.println(-16>>2);
//-13的补码为:11111111 11111111 11111111 11101101
System.out.println(-15>>2);
//-13的补码为:11111111 11111111 11111111 11101110
System.out.println(-14>>2);
//-13的补码为:11111111 11111111 11111111 11101111
System.out.println(-13>>2);
//-12的补码为:11111111 11111111 11111111 11110100
System.out.println(-12>>2);
//-11的补码为:11111111 11111111 11111111 11110101
System.out.println(-11>>2);
//-10的补码为:11111111 11111111 11111111 11110110
System.out.println(-10>>2);
System.out.println("=========================================");
//-9的补码为:11111111 11111111 11111111 11110111
System.out.println(-9/4-1);
System.out.println(-9>>2);
//-8的补码为:11111111 11111111 11111111 11111000
System.out.println(-8/4);
System.out.println(-8>>2);
//-7的补码为:11111111 11111111 11111111 11111001
System.out.println(-7/4-1);
System.out.println(-7>>2);
//-6的补码为:11111111 11111111 11111111 11111010
//>>右移符号位不动,高位补1
//11111111 11111111 11111111 11111110 为-1的补码、
// System.out.println(-7/2/2);
System.out.println(-6/4-1);
System.out.println(-6>>2);// -2 -6/2/2-1
//-5的补码为:11111111 11111111 11111111 11111011
//>>右移符号位不动,高位补1
//11111111 11111111 11111111 11111110 为-1的补码
// System.out.println(-6/2/2);
System.out.println(-5/4-1);
System.out.println(-5>>2);// -2
//-4的补码为:11111111 11111111 11111111 11111100
//>>右移符号位不动,高位补1
//11111111 11111111 11111111 11111111 为-1的补码
// System.out.println(-5/2/2);
System.out.println(-4/4);
System.out.println(-4>>2);// -1
// System.out.println(-4/2/2);
System.out.println(-3/4-1);
System.out.println(-3>>2);// -1
//整数 n/2/2=n/4 负数 n/2/2 = n/4如果n%4取余数为0,则为n/4,否则为n/4-1

System.out.println(3>>>2);//3/2/2 =0
//-3的补码为:11111111 11111111 11111111 11111101
//>>>右移符号位移动,高位补0
//00111111 11111111 11111111 11111111 为-1的补码
System.out.println(-3>>>2);//2^30-1 1073741823

System.out.println(3<<2);//3*2*2 = 12
//-3的补码为:11111111 11111111 11111111 11111101
//<<左移符号位移动,高位补0
//11111111 11111111 11111111 11110100 为的补码-12
System.out.println(-3<<2);//-3*2*2 = -12

//判断奇偶性
System.out.println((4&1)==1?"奇数":"偶数");
System.out.println((4|0)==1?"奇数":"偶数");

//取反
System.out.println(~0);//-1
System.out.println(~1);//-2
System.out.println(~-2);// ~n= -(n+1)

//异或
//0101
System.out.println(4^8);//1^1=0 0^0=0 0^1=1 a^b^a=b
System.out.println("==========");

System.out.println(1^1);
System.out.println(1^0);
System.out.println(0^0);
//a与b交换
int a = 10;
int b = 12;
a = a^b;
b = a^b;//a^b^b = a;
a = a^b;//a^b^a = b;
System.out.println(a);
System.out.println(b);


System.out.println("===================");
System.out.println(4<<2);
System.out.println(-4<<2);
System.out.println("==============");
//负数 -(n-1)+1
//正数 n-0
System.out.println((-5^(-5>>31))-(-5>>31));

}
}

运行结果:

参考博客:

https://blog.csdn.net/yuxiangaaaaa/article/details/78455687

https://www.cnblogs.com/hapjin/p/5839797.html

https://www.cnblogs.com/findbetterme/p/10787118.html

https://www.modb.pro/db/72397

https://www.cnblogs.com/findbetterme/p/10787118.html