二进制实战技巧

匠心零度 转载请注明原创出处,谢谢!java

说在前面

看过稍微底层点的源码的人应该都会了解、熟悉里面多多少少会碰到二进制相关操做,由于这个以前还写了一篇java二进制相关基础的基础篇,本篇准备写一些二进制实战技巧相关内容。网络

主题

  • 判断一个数是不是2的幂次方的方法。
  • 操做位表明类型。
  • 非2的幂次方转换为2的幂次方。

判断一个数是不是2的幂次方的方法

若是该数是无符号整数,可使用:框架

private static boolean isPowerOfTwo(int val) {
      return (val & (val-1)) == 0;
}
复制代码

若是一个数是2的n次方,那么这个数用二进制表示时其最高位为1,其他位为0,(val-1)和val都错开了0和1,那么&必定是0。性能

若是该数是无符号整数,也可使用:spa

private static boolean isPowerOfTwo(int val) {
      return (val & -val) == val;
}
复制代码

若是一个数是2的n次方,那么这个数用二进制表示时其最高位为1,其他位为0,(val & -val)就是获取最右1的位,那么若是和val等于就是了。code

扩展下,如何判断一个无符号数是2的n次方-1cdn

private static boolean isPowerOfTwoLoseOne(int val) {
      return (val & (val+1)) == 0;
}
复制代码

理由其实和上面相似了。blog

操做位表明类型

JDK SelectionKey有四种操做类型,分别为:ci

OP_READ = 1 << 0;
OP_WRITE = 1 << 2;
OP_CONNECT = 1 << 3;
OP_ACCEPT = 1 << 4复制代码

因为只有四种网络操做类型,因此用4 bit就能够表示全部的网络操做位,因为JAVA语言没有bit类型,因此使用了整形来表示,每一个操做位表明一种网络操做类型,分别为:0000一、00100、01000、10000,这样作的好处是能够很是方便的经过位操做来进行网络操做位的状态判断和状态修改,提高操做性能。get

**说明:**依稀记得RocketMQ里面好像也是相似,有一个当磁盘空间大于90%的时候不给写权限就是相似控制的,后续分析RocketMQ源码的时候会进行说明。

非2的幂次方转换为2的幂次方

在jdk不少集合框架里面,不知道大家还发现了,集合的大小都会是2的幂次方,哈哈,因此就引出了下面的话题。

int cap = ((initialCapacity >= (MAXIMUM_CAPACITY >>> 1)) ?
                   MAXIMUM_CAPACITY :


    private static final int tableSizeFor(int c) {
        int n = c - 1;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
    }
复制代码

实例化ConcurrentHashMap时带参数时,会根据参数调整table的大小,确保table的大小老是2的幂次方,调用tableSizeFor的时候每次返回的都是大于等于离该数最近的2的幂次方的数。好比调用tableSizeFor传入c为151的时候 比151大的2的幂次方的数就是256了,核心就是上面的位运算操做。

刚刚上面是求一个数离它最近的大于等于2的幂次方的数,若是求小于等于2的幂次方的数,咱们应该怎么办呢?

private static final int tableSizeFor(int n) {
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        return  n-(n>>1);
    }
复制代码

**说明:**因为集合的大小都会是2的幂次方,那么求table大小的0.75倍的时候,可使用(n - (n >>> 2))便可,取模的时候,可使用hash & 0x7FFFFFFF来进行操做便可。

结束语

上面的都是零度发现的一些实战,若是你发现什么更好的二进制实战,欢迎在留言区积极留言评论。!!!


若是读完以为有收获的话,欢迎点赞、关注、加公众号【匠心零度】,查阅更多精彩历史!!!

相关文章
相关标签/搜索