乘法与位运算
7 4 => 7 22 => 7 << 2
7 8 => 7 23 => 7 << 3
7 12 => 7 (8 + 4) => 7 23 + 7 22 => 7 << 3 + 7 << 2
% 与 &
如果对一个数进行2的n次冥取模%运算,则可以使用位运算取代:
public static void main(String[] args) {
int n = 891;
int a = 8;
System.out.println(n % a);
System.out.println(n & (a - 1));
}
// 输出的结果都为3
判断奇偶数
正常写法:
if( n % 2) == 01
// n 是个奇数
}
位运算:
if(n & 1 == 1){
// n 是个奇数。
}
获取固定长度的全1或类似1000
// 获取4位全1:00001111
int a = (1 << 4) - 1;
System.out.println(Integer.toBinaryString(a));
// 获取00001000
a = 1 << 3;
System.out.println(Integer.toBinaryString(a));
获取高位或低位
// 如果Int的值在8位范围内,获取int的高4位
int a = 167; // 10100111
System.out.println(Integer.toBinaryString(a >>> 4)); // 1010
// 如果Int的值在8位范围内,获取int的低4位
int b = (1 << 4) - 1;
System.out.println(Integer.toBinaryString(a & b)); // 0111
int a = (int) (Integer.MAX_VALUE / 2 * 1.1);
System.out.println(Integer.toBinaryString(a)); // 1000110011001100110011001100101
// 获取int的高16位
System.out.println(Integer.toBinaryString(a >>> 16)); // 100011001100110
// 获取int的低16位
int b = (1 << 16) - 1;
System.out.println(Integer.toBinaryString(a & b)); // 110011001100101
权限应用
权限说明 | 二进制 | 十进制 | 代码 | 说明 |
---|---|---|---|---|
查看 | 00001 | 1 | 1 | |
修改 | 00011 | 3 | (1 << 2) - 1 | 有修改权限的同时拥有查看权限 |
删除 | 00101 | 5 | (1 << 2) + 1 | 有删除权限的同时拥有查看权限,无修改权限 |
修改 + 删除 | 00111 | 7 | (1 << 3) - 1 | 同时拥有修改+删除权限,同时拥有查看权限 |
新增 | 01111 | 15 | (1 << 4) - 1 | 有新增权限的同时拥有查看、修改、删除权限 |
监控 | 10111 | 23 | (1 << 4) + (1 << 3) - 1 | 有监控权限的同时拥有查看权限、修改权限、删除权限,无新增权限 |
新增+监控 | 11111 | 31 | (1 << 5) -1 | 有新增+监控权限爱你,同时拥有查看、修改、删除权限 |
权限的判断
- 判断是否有查看权限: n & 1 != 0;
- 判断是否有修改权限: n & 0b00010 != 0;
- 判断是否有删除权限:n & 0b00100 != 0;
- 判断是否有新增权限:n & 0b01000 != 0;
-
增加权限
增加修改权限:n | 0b00011
- 增加删除权限:n | 0b00101
- 增加新增权限:n | 0b01111
- 增加监控权限:n | 0b10111
完整权限设计代码
```java package com.bestlink.demo.demo9;
/**
- @author jeffrey
@date 6/30/21 11:39 AM */ public class Authority {
// 查看权限 private final int VIEW_AUTHORITY = 1; // 新增权限 private final int ADD_AUTHORITY = 1 << 1; // 修改权限 private final int MODIFY_AUTHORITY = 1 << 2; // 删除权限 private final int DELETE_AUTHORITY = 1 << 3; // 监控权限 private final int CONTROL_AUTHORITY = 1 << 4;
public boolean hasViewAuthority(int n) {
return (n & VIEW_AUTHORITY) != 0;
}
public boolean hasModifyAuthority(int n) {
return (n & MODIFY_AUTHORITY) != 0;
}
public boolean hasDeleteAuthority(int n) {
return (n & DELETE_AUTHORITY) != 0;
}
public boolean hasAddAuthority(int n) {
return (n & ADD_AUTHORITY) != 0;
}
public boolean hasControlAuthority(int n) {
return (n & CONTROL_AUTHORITY) != 0;
}
public int addViewAuthority(int n) {
return n | VIEW_AUTHORITY;
}
public int addModifyAuthority(int n) {
return n | MODIFY_AUTHORITY;
}
public int addDeleteAuthority(int n) {
return n | DELETE_AUTHORITY;
}
public int addAddAuthority(int n) {
return n | ADD_AUTHORITY;
}
public int addControlAuthority(int n) {
return n | CONTROL_AUTHORITY;
}
public int removeViewAuthority(int n) {
return n & (~VIEW_AUTHORITY);
}
public int removeModifyAuthority(int n) {
return n & (~MODIFY_AUTHORITY);
}
public int removeDeleteAuthority(int n) {
return n & (~DELETE_AUTHORITY);
}
public int removeAddAuthority(int n) {
return n & (~ADD_AUTHORITY);
}
public int removeControlAuthority(int n) {
return n & (~CONTROL_AUTHORITY);
}
// 动态传权限进行权限的校验、新增、删除 public boolean hasAuthority(int n ,int authority) {
return (n & authority) != 0;
} public int addAuthority(int n, int authority) {
return n | authority;
} public int removeAuthority(int n, int authority) {
return n & (~authority);
}
public static void main(String[] args) {
Test test = new Test();
int n = 0;
System.out.println("增加查看权限: " + Integer.toBinaryString(test.addViewAuthority(n)));
System.out.println("增加修改权限: " + Integer.toBinaryString(test.addModifyAuthority(n)));
System.out.println("增加删除权限: " + Integer.toBinaryString(test.addDeleteAuthority(n)));
System.out.println("增加新建权限: " + Integer.toBinaryString(test.addAddAuthority(n)));
System.out.println("增加监控权限: " + Integer.toBinaryString(test.addControlAuthority(n)));
System.out.println("增加删除和修改权限: " + Integer.toBinaryString(test.addDeleteAuthority(test.addModifyAuthority(n))));
System.out.println("增加监控和新建权限: " + Integer.toBinaryString(test.addControlAuthority(test.addAddAuthority(n))));
System.out.println("移除新建权限: " + Integer.toBinaryString(test.removeAddAuthority(test.addDeleteAuthority(test.addModifyAuthority(n)))));
System.out.println("移除新建权限: " + Integer.toBinaryString(test.removeAddAuthority(test.addDeleteAuthority(test.addAddAuthority(n)))));
} } ```
判断某个数是不是2的整数次冥
如果某个数是2的整数次冥,则这个数的二进制类似:0b10000,由1个1后面全是0组成,只需要判断0b10000 & 0b01111是否等于0即可判断,而0b01111又等于0b10000 - 1得到,所以判断代码如下:
(num & (num - 1)) == 0;
判断某个整数的二进制表示中1的个数
int count1(unsigned int n){
int res = 0;
while(n != 0){
res += n & 1;
n >>= 1;
}
return res;
}
异或
结合律和交换律在加密解密上的应用
A ^ B = C => C ^ A = B => C ^ B = A
上文我们可以把A认为是需要加密的数据,B认为是密钥 C是加密后的数据。
上文的推导:
A ^ B = C; => A ^ B ^ A = C ^ A; => A ^ A ^ B = C ^ A;
=> 0 ^ B = C ^ A; => C ^ A = B;
C ^ B = C ^ A ^ C; => C ^ B = C ^ C ^ A; => C ^ B = 0 ^ A => C ^ B = A;
结合律和交换律在参数交换上的应用
给定两个变量:x,y 在不引入第三个变量的前提下交换两个变量
// 由异或的传递律和分解律得以下结果:
x ^ y = z;
x = z ^ y;
y = z ^ x;
// 交换后两个赋值语句即可交换x, y的值,即:
public static void main(String[] args) {
int x = 3;
int y = 4;
int z = x ^ y;
x = z ^ x;
y = z ^ y;
System.out.println(x);
System.out.println(y);
}
取整
只使用JS,java不支持
~~ -3.14 // 3
3.14 >> 0) // 3
3.14 << 0) // 3
3.14 | 0 // 3
3.14 >>> 0 // 3, 不能对负数进行该操作
3.14 ^ 0 // 3
汉明重量
汉明重量是一串符号中非零符号的个数。因此它等同于同样长度的全零符号串的汉明距离。在最为常见的数据位符号串中,它是1的个数。
通过swar方法计算汉明重量:
public static void main(String[] args) throws Exception {
int i = 342;
System.out.println(Integer.toBinaryString(i));
System.out.println(swar(i));
}
public static int swar(int i)
{
i = (i & 0x55555555) + ((i >> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
i = (i & 0x0F0F0F0F) + ((i >> 4) & 0x0F0F0F0F);
i = (i * (0x01010101) >> 24);
return i;
}