美文网首页探索JDK
Integer.highestOneBit(int i) 和 I

Integer.highestOneBit(int i) 和 I

作者: 苏小小北 | 来源:发表于2018-10-28 00:15 被阅读0次
    IG战胜G2,时隔4年中国队再次晋级决赛

    1. 前言


    Integer.highestOneBit(int i):求二进制除了最高位1保留,其他全部设置为0的,对应的数字。
    Integer.lowestOneBit(int i):求二进制除了最高位1保留,其他全部设置为0的,对应的数字。
    在之前的文章中曾经介绍过jdk求最高位(最低位)连续0的个数,基本求法与之前一致,是利用位运算来计算。但是,在lowestOneBit方法是非常巧妙的,下面我们就一探究竟。

    2. 源码


    (1) Integer.highestOneBit

    先看Integer.highestOneBit(int i):

        public static int highestOneBit(int i) {
            // HD, Figure 3-1
            i |= (i >>  1);// 1
            i |= (i >>  2);// 2
            i |= (i >>  4);// 3
            i |= (i >>  8);// 4
            i |= (i >> 16);// 5
            return i - (i >>> 1);// 6
        }
    

    乍一看,不太明白什么意思,那一步步的解析:
    首先,做个假设,假设 i 的最高位 1 在 第 j 位
    第1步:
    i |= (i >> 1)
    将 j 位右边 1 位也变成 1
    第2步:
    i |= (i >> 2);
    将 j 位右边 4 位全变成 1
    第3步:
    i |= (i >> 4);
    将 j 位右边 8 位全变成 1
    第4步:
    i |= (i >> 8);
    将 j 位右边 16 位全变成 1
    第5步:
    i |= (i >> 16);
    将 j 位右边 32 位也变成 1
    第6步:这时,j位右边全是1,减去 i >>> 1 即为所求
    i - (i >>> 1);
    就得到结果

    (1) Integer.lowestOneBit

    再看Integer.lowestOneBit(int i):

        public static int lowestOneBit(int i) {
            // HD, Section 2-1
            return i & -i;
        }
    

    设 i 为正整数,则 i 的补码就为原码,设为 0a1b(0开头的32位,a表示任意的二进制,b表示全0的二进制,a和b的个数总和为32-2=30)
    那么 -i 的
    原码 1a1b(1开头的32位)
    反码 为
    除了符号位之外,全部取反:1-a0c(-a表示a的二进制全相反形式01相换,c表示全1的二进制)
    补码
    反码 + 1:1-a1b(b表示全1的二进制)
    那么,i & -i 的结果为,
    0a1b & (1-a1b) = 0a'1b(a'表示与a相同个数0的二进制,b为全0二进制)
    所以,i & -i 即为所求

    3.后言

    最高位还是比较常见的思路,最低位求法就比较精辟了。

    其他

    本人也是在慢慢学习中,如有错误还请原谅、敬请指出,谢谢!

    相关文章

      网友评论

        本文标题:Integer.highestOneBit(int i) 和 I

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