位运算的妙用

判断2的整数次幂

2的整数次幂,二进制里只有一个1, (n & (n - 1)的值为0

public static boolean isPowerOf2(int n) {
    return  n > 0 && (n & (n - 1)) == 0;
}

快速取余

  • x%n,如果n是2的整数次幂,可以转换为 x&(n-1)
public static int mod(int x, int n) {
    if ((n & (n - 1)) == 0) {
        return x & (n - 1); // n是2的整数次幂
    } else {
        return x % n; // n不是2的整数次幂
    }
}

判断奇偶

public static boolean isOdd(int n) {
    return (n & 1) == 1;
}

判断两个数异号

public static boolean isDiffSign(int a, int b) {
    return (a ^ b) < 0;
}

取二进制最高位

public static int highestOneBit(int i) {
    // HD, Figure 3-1
    i |= (i >>  1); // 经过这一步后,最高位的1把右边相邻的1位设置成了1 
    i |= (i >>  2); // 经过这一步后,最高位的3把右边相邻的1位设置成了1
    i |= (i >>  4); // 经过这一步后,最高位的7把右边相邻的1位设置成了1
    i |= (i >>  8); // 经过这一步后,最高位的15把右边相邻的1位设置成了1
    i |= (i >> 16); // 经过这一步后,最高位的31把右边相邻的1位设置成了1,也就是说从最高位的1开始到最低位,全是1了
    return i - (i >>> 1); // 经过这一步, 只保留了最高位的1
}

取二进制最低位

public static int lowestOneBit(int i) {
    // 假设二进制位 ???1000
    // -i -> (~i)+1 -> ???1000
    // i&-i -> 0001000
    return i & -i; 
}

计算二进制中1的个数/计算汉明权重

public static int bitCount(int i) {
    // 第一步是按2位一组,对二进制进行分组,并计算一组中1的个数
    // 后续步骤就是不断把分组进行合并求和
    i = i - ((i >>> 1) & 0x55555555); // 把bit按2个一组进行分组,经过这一步运算后,2个bit组成的数字就是原来这2个bit位置1的个数, 00 -> 00 -> 0, 01 -> 01 -> 1, 10 -> 01 -> 1, 11 -> 10 -> 2
    i = (i & 0x33333333) + ((i >>> 2) & 0x33333333); // 把2个bit的分组进行合并,变成4个bit的分组,用低位3个bit存储原来4个bit中1的个数
    i = (i + (i >>> 4)) & 0x0f0f0f0f; // 把4个bit的分组进行合并,变成8个bit的分组,用低位4个bit存储原来4个bit中1的个数
    i = i + (i >>> 8); // 把8个bit的分组进行合并,变成16个bit的分组,用低位5个bit存储原来4个bit中1的个数
    i = i + (i >>> 16); // 把16个bit的分组进行合并,变成32个bit的分组,用低位6个bit存储原来4个bit中1的个数
    return i & 0x3f; // 取出低位的6个bit,就是原二进制中1的个数
}

英文字符转大写

(‘b’ & ‘') == ‘B’
(‘B’ & '
’) == ‘B’

英文字符转小写

(‘a’ | ’ ') == ‘a’
(‘A’ | ’ ') == ‘a’

英文字符大小写互转

(‘d’ ^ ’ ') == ‘D’
(‘D’ ^ ’ ') == ‘d’

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值