位运算

作者: wuchao226 | 来源:发表于2021-05-10 15:33 被阅读0次

二进制数据是用0和1两个数码来表示的数。它的基数为2,进位规则是逢二进一,借位规则是借一当二。因为它只使用0、1两个数字符号,非常简单方便。

常用位运算
  • 位与 & (1&1=1 0&0=0 1&0=0)
  • 位或 | (1|1=1 0|0=0 1|0=1)
  • 位非 (1=0 ~0=1)
  • 位异或 ^ (1^1=0 1^0=1 0^0=0)
  • 有符号右移>>(若正数,高位补0,负数,高位补1)
  • 有符号左移<<
  • 无符号右移>>>(不论正负,高位均补0)

有趣的取模性质:取模 a % (2^n) 等价于 a & (2^n - 1),所以在 map 里的数组个数一定是 2 的乘方数,计算 key 值在哪个元素中的时候,就用位运算来快速定位。

位运算结果

/**
 * 位运算
 */
public class IntToBinary {

    public static void main(String[] args) {
        System.out.println("the 4 is : " + Integer.toBinaryString(4));
        System.out.println("the 6 is : " + Integer.toBinaryString(6));
        //位与&(真真为真 真假为假 假假为假)
        System.out.println("the 4&6 is : " + Integer.toBinaryString(6 & 4));
        //位或|(真真为真 真假为真 假假为假)
        System.out.println("the 4|6 is : " + Integer.toBinaryString(6 | 4));
        //位非~
        System.out.println("the ~4 is : " + Integer.toBinaryString(~4));
        //位异或^(真真为假 真假为真 假假为假)
        System.out.println("the 4^6 is : " + Integer.toBinaryString(6 ^ 4));
        //有符号右移>>(若正数,高位补0,负数,高位补1)
        System.out.println("the 4>>1 is : " + Integer.toBinaryString(4 >> 1));
        //有符号左移<<(若正数,高位补0,负数,高位补1)
        System.out.println("the 4<<1 is : " + Integer.toBinaryString(4 << 1));
        //无符号右移>>>(不论正负,高位均补0)
        System.out.println("the 234567 is : " + Integer.toBinaryString(234567));
        System.out.println("the 234567>>>4 is : " + Integer.toBinaryString(234567 >>> 4));
        //无符号右移>>>(不论正负,高位均补0)
        System.out.println("the -4 is : " + Integer.toBinaryString(-4));
        System.out.println("the -4>>>4 is : " + Integer.toBinaryString(-4 >>> 4));
        System.out.println(Integer.parseInt(Integer.toBinaryString(-4 >>> 4), 2));

        //取模a % (2^n) 等价于 a & (2^n - 1)
        System.out.println("the 345 % 16 is : " + (345 % 16) + " or " + (345 & (16 - 1)));

        System.out.println("Mark hashCode is : " + "Mark".hashCode() + "="
                + Integer.toBinaryString("Mark".hashCode()));
        System.out.println("Bill hashCode is : " + "Bill".hashCode() + "="
                + Integer.toBinaryString("Bill".hashCode()));
    }
}

打印结果:

the 4 is : 100
the 6 is : 110
the 4&6 is : 100
the 4|6 is : 110
the ~4 is : 11111111111111111111111111111011
the 4^6 is : 10
the 4>>1 is : 10
the 4<<1 is : 1000
the 234567 is : 111001010001000111
the 234567>>>4 is : 11100101000100
the -4 is : 11111111111111111111111111111100
the -4>>>4 is : 1111111111111111111111111111
268435455
the 345 % 16 is : 9 or 9
Mark hashCode is : 2390765=1001000111101011101101
Bill hashCode is : 2070567=111111001100000100111

位运算运用场景

  • Java中的类修饰符、成员变量修饰符、方法修饰符
  • Java容器中的 HashMap 和 ConcurrentHashMap 的实现
  • 权限控制或者商品属性
  • 简单可逆加密(1^1=0 ; 0^1=1 )

实战:权限控制

/**
 * 位运算的运用-权限控制,add,query,modify,del
 */
public class Permission {
    private static final int ALLOW_SELECT = 1 << 0;
    private static final int ALLOW_INSERT = 1 << 1;
    private static final int ALLOW_UPDATE = 1 << 2;
    private static final int ALLOW_DELETE = 1 << 3;

    //当前的权限状态
    private int flag;

    public void setPermission(int permission) {
        flag = permission;
    }

    /*增加权限,可以一项或者多项*/
    public void addPermission(int permission) {
        flag = flag | permission;
    }

    /*删除权限,可以一项或者多项*/
    public void disablePermission(int permission) {
        flag = flag & ~permission;
    }

    /*是否拥有某些权限*/
    public boolean isAllow(int permission) {
        return (flag & permission) == permission;
    }

    /*是否不拥有某些权限*/
    public boolean isNotAllow(int permission) {
        return (flag & permission) == 0;
    }

    public static void main(String[] args) {
        int flag = 15;
        Permission permission = new Permission();
        permission.setPermission(flag);
        permission.disablePermission(ALLOW_DELETE | ALLOW_INSERT);
        System.out.println("ALLOW_SELECT=" + permission.isAllow(ALLOW_SELECT));
        System.out.println("ALLOW_INSERT=" + permission.isAllow(ALLOW_INSERT));
        System.out.println("ALLOW_UPDATE=" + permission.isAllow(ALLOW_UPDATE));
        System.out.println("ALLOW_DELETE=" + permission.isAllow(ALLOW_DELETE));
    }
}

打印结果:

ALLOW_SELECT=true
ALLOW_INSERT=false
ALLOW_UPDATE=true
ALLOW_DELETE=false

使用位运算的优劣势:
节省很多代码量、效率高、属性变动影响小、不直观。

相关文章

  • 3、小众运算符の大课堂(一)

    较为简单の位运算符: & 位与运算| 位或运算^ 位异或运算~ 位取反运算 举例: 要做位运算,首先要把数据转...

  • 位运算及其应用

    内容概要: 位运算基本操作 基于位运算的状态压缩 位运算经典应用 位运算解N皇后问题 位运算 符号描述规则&与1&...

  • 位运算及用位运算实现权限控制

    请自行补习位运算相关知识 位运算 位运算示例 权限控制

  • 开发基础随笔之位运算符(Bitwise Operators)

    位运算符,属于算术运算符 按位逻辑运算符: 位移运算符: 位运算符的运算数只能是整数 位移运算符:按位左移 a<<...

  • 强大的位运算符

    位取反运算符 位取反运算符(~)是对所有位的数字进行取反操作位取反运算符.png 位与运算符 位与运算符(&)可以...

  • 位运算

    位运算 1. &:按位与 规律:一假则假任何位上的数和1相&得到的结果还是那个数 2. |:按位或 规律:一真则真...

  • 位运算

    https://leetcode.com/problems/gray-code/description/这个位运算...

  • 位运算

    位运算符比一般的算术运算符速度要快,而且可以实现一些算术运算符不能实现的功能。如果要开发高效率程序,位运算符是必不...

  • 位运算

    1.不用加减乘除做加法 解法:分为三步①各位相加不进位,即先按位异或;②做进位,按位与并左移位;③结果相加,直至没...

  • 位运算

    位运算不仅可以简化某些复杂的操作,而且具有更快的计算速度。典型的应用就是除法,交换两个数值,以及在一个数组中寻找只...

网友评论

      本文标题:位运算

      本文链接:https://www.haomeiwen.com/subject/azxidltx.html