Integer.highestOneBit(int i) 和 Integer.lowestOneBit(int i)

Integer.highestOneBit(int i) 和 Integer.lowestOneBit(int i)_第1张图片
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) 和 Integer.lowestOneBit(int i))