乘法与位运算

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次冥取模%运算,则可以使用位运算取代:

  1. public static void main(String[] args) {
  2. int n = 891;
  3. int a = 8;
  4. System.out.println(n % a);
  5. System.out.println(n & (a - 1));
  6. }
  7. // 输出的结果都为3

判断奇偶数

正常写法:

  1. if( n % 2) == 01
  2. // n 是个奇数
  3. }

位运算:

  1. if(n & 1 == 1){
  2. // n 是个奇数。
  3. }

获取固定长度的全1或类似1000

  1. // 获取4位全1:00001111
  2. int a = (1 << 4) - 1;
  3. System.out.println(Integer.toBinaryString(a));
  4. // 获取00001000
  5. a = 1 << 3;
  6. System.out.println(Integer.toBinaryString(a));

获取高位或低位

  1. // 如果Int的值在8位范围内,获取int的高4位
  2. int a = 167; // 10100111
  3. System.out.println(Integer.toBinaryString(a >>> 4)); // 1010
  4. // 如果Int的值在8位范围内,获取int的低4位
  5. int b = (1 << 4) - 1;
  6. System.out.println(Integer.toBinaryString(a & b)); // 0111
  7. int a = (int) (Integer.MAX_VALUE / 2 * 1.1);
  8. System.out.println(Integer.toBinaryString(a)); // 1000110011001100110011001100101
  9. // 获取int的高16位
  10. System.out.println(Integer.toBinaryString(a >>> 16)); // 100011001100110
  11. // 获取int的低16位
  12. int b = (1 << 16) - 1;
  13. 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 & 0b10000 != 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) {

    1. return (n & VIEW_AUTHORITY) != 0;

    }

    public boolean hasModifyAuthority(int n) {

    1. return (n & MODIFY_AUTHORITY) != 0;

    }

    public boolean hasDeleteAuthority(int n) {

    1. return (n & DELETE_AUTHORITY) != 0;

    }

    public boolean hasAddAuthority(int n) {

    1. return (n & ADD_AUTHORITY) != 0;

    }

    public boolean hasControlAuthority(int n) {

    1. return (n & CONTROL_AUTHORITY) != 0;

    }

    public int addViewAuthority(int n) {

    1. return n | VIEW_AUTHORITY;

    }

    public int addModifyAuthority(int n) {

    1. return n | MODIFY_AUTHORITY;

    }

    public int addDeleteAuthority(int n) {

    1. return n | DELETE_AUTHORITY;

    }

    public int addAddAuthority(int n) {

    1. return n | ADD_AUTHORITY;

    }

    public int addControlAuthority(int n) {

    1. return n | CONTROL_AUTHORITY;

    }

    public int removeViewAuthority(int n) {

    1. return n & (~VIEW_AUTHORITY);

    }

    public int removeModifyAuthority(int n) {

    1. return n & (~MODIFY_AUTHORITY);

    }

    public int removeDeleteAuthority(int n) {

    1. return n & (~DELETE_AUTHORITY);

    }

    public int removeAddAuthority(int n) {

    1. return n & (~ADD_AUTHORITY);

    }

    public int removeControlAuthority(int n) {

    1. return n & (~CONTROL_AUTHORITY);

    }

    // 动态传权限进行权限的校验、新增、删除 public boolean hasAuthority(int n ,int authority) {

    1. return (n & authority) != 0;

    } public int addAuthority(int n, int authority) {

    1. return n | authority;

    } public int removeAuthority(int n, int authority) {

    1. return n & (~authority);

    }

    public static void main(String[] args) {

    1. Test test = new Test();
    2. int n = 0;
    3. System.out.println("增加查看权限: " + Integer.toBinaryString(test.addViewAuthority(n)));
    4. System.out.println("增加修改权限: " + Integer.toBinaryString(test.addModifyAuthority(n)));
    5. System.out.println("增加删除权限: " + Integer.toBinaryString(test.addDeleteAuthority(n)));
    6. System.out.println("增加新建权限: " + Integer.toBinaryString(test.addAddAuthority(n)));
    7. System.out.println("增加监控权限: " + Integer.toBinaryString(test.addControlAuthority(n)));
    8. System.out.println("增加删除和修改权限: " + Integer.toBinaryString(test.addDeleteAuthority(test.addModifyAuthority(n))));
    9. System.out.println("增加监控和新建权限: " + Integer.toBinaryString(test.addControlAuthority(test.addAddAuthority(n))));
    10. System.out.println("移除新建权限: " + Integer.toBinaryString(test.removeAddAuthority(test.addDeleteAuthority(test.addModifyAuthority(n)))));
    11. System.out.println("移除新建权限: " + Integer.toBinaryString(test.removeAddAuthority(test.addDeleteAuthority(test.addAddAuthority(n)))));

    } } ```

判断某个数是不是2的整数次冥

如果某个数是2的整数次冥,则这个数的二进制类似:0b10000,由1个1后面全是0组成,只需要判断0b10000 & 0b01111是否等于0即可判断,而0b01111又等于0b10000 - 1得到,所以判断代码如下:

  1. (num & (num - 1)) == 0;

判断某个整数的二进制表示中1的个数

  1. int count1(unsigned int n){
  2. int res = 0;
  3. while(n != 0){
  4. res += n & 1;
  5. n >>= 1;
  6. }
  7. return res;
  8. }

异或

结合律和交换律在加密解密上的应用

  1. A ^ B = C => C ^ A = B => C ^ B = A

上文我们可以把A认为是需要加密的数据,B认为是密钥 C是加密后的数据。
上文的推导:

  1. A ^ B = C; => A ^ B ^ A = C ^ A; => A ^ A ^ B = C ^ A;
  2. => 0 ^ B = C ^ A; => C ^ A = B;
  3. C ^ B = C ^ A ^ C; => C ^ B = C ^ C ^ A; => C ^ B = 0 ^ A => C ^ B = A

结合律和交换律在参数交换上的应用

给定两个变量:x,y 在不引入第三个变量的前提下交换两个变量

  1. // 由异或的传递律和分解律得以下结果:
  2. x ^ y = z;
  3. x = z ^ y;
  4. y = z ^ x;
  5. // 交换后两个赋值语句即可交换x, y的值,即:
  6. public static void main(String[] args) {
  7. int x = 3;
  8. int y = 4;
  9. int z = x ^ y;
  10. x = z ^ x;
  11. y = z ^ y;
  12. System.out.println(x);
  13. System.out.println(y);
  14. }

取整

只使用JS,java不支持

  1. ~~ -3.14 // 3
  2. 3.14 >> 0) // 3
  3. 3.14 << 0) // 3
  4. 3.14 | 0 // 3
  5. 3.14 >>> 0 // 3, 不能对负数进行该操作
  6. 3.14 ^ 0 // 3

汉明重量

汉明重量是一串符号中非零符号的个数。因此它等同于同样长度的全零符号串的汉明距离。在最为常见的数据位符号串中,它是1的个数。
通过swar方法计算汉明重量:

  1. public static void main(String[] args) throws Exception {
  2. int i = 342;
  3. System.out.println(Integer.toBinaryString(i));
  4. System.out.println(swar(i));
  5. }
  6. public static int swar(int i)
  7. {
  8. i = (i & 0x55555555) + ((i >> 1) & 0x55555555);
  9. i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
  10. i = (i & 0x0F0F0F0F) + ((i >> 4) & 0x0F0F0F0F);
  11. i = (i * (0x01010101) >> 24);
  12. return i;
  13. }