二进制实战技巧
匠心零度 转载请注明原创出处,谢谢!
说在前面
看过稍微底层点的源码的人应该都会了解、熟悉里面多多少少会碰到二进制相关操作,因为这个之前还写了一篇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。
如果该数是无符号整数,也可以使用:
private static boolean isPowerOfTwo(int val) { return (val & -val) == val; }
如果一个数是2的n次方,那么这个数用二进制表示时其最高位为1,其余位为0,(val & -val)就是获取最右1的位,那么如果和val等于就是了。
扩展下,如何判断一个无符号数是2的n次方-1
private static boolean isPowerOfTwoLoseOne(int val) { return (val & (val+1)) == 0; }
理由其实和上面类似了。
操作位代表类型
JDK SelectionKey有四种操作类型,分别为:
OP_READ = 1 << 0; OP_WRITE = 1 << 2; OP_CONNECT = 1 << 3; OP_ACCEPT = 1 << 4。
由于只有四种网络操作类型,所以用4 bit就可以表示所有的网络操作位,由于JAVA语言没有bit类型,所以使用了整形来表示,每个操作位代表一种网络操作类型,分别为:0001、0010、0100、1000,这样做的好处是可以非常方便的通过位操作来进行网络操作位的状态判断和状态修改,提升操作性能。
说明:依稀记得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来进行操作即可。
结束语
上面的都是零度发现的一些实战,如果你发现什么更好的二进制实战,欢迎在留言区积极留言评论。!!!
如果读完觉得有收获的话,欢迎点赞、关注、加公众号【匠心零度】,查阅更多精彩历史!!!
原文地址:https://www.cnblogs.com/jiangxinlingdu/p/8278619.html
相关推荐
-
【同余方程组】POJ1006 生理周期 Java基础
2019-10-8
-
Feign-手动创建FeignClient Java基础
2020-5-28
-
关于成都移动宽带访问开源中国看不到图片的问题分析 Java基础
2020-7-3
-
【推荐】互联网或技术多平台,一文多发小工具! Java基础
2019-9-22
-
YOLOv1/v2/v3简述 | 目标检测 Java基础
2020-7-2
-
两个星期,用Flutter撸个APP Java基础
2019-9-22
-
一起来学Java8(四)——复合Lambda Java基础
2020-6-15
-
总结!Java8 增强的Future:CompletableFuture Java基础
2020-5-30
-
Java 最常见的 200+ 面试题:面试必备 Java基础
2019-8-20
-
关于 Java 类加载器的这一点,市面上没有任何一本图书讲到 Java基础
2020-5-28