android

Integer类中的numberOfLeadingZeros(i

2018-03-20  本文已影响0人  向天葵

源码:

   public static int numberOfLeadingZeros(int i) {
        //
        if (i == 0)    //步骤一
            return 32;
        int n = 1;  
        //步骤二
        if (i >>> 16 == 0) { n += 16; i <<= 16; }//分析一
        if (i >>> 24 == 0) { n +=  8; i <<=  8; }
        if (i >>> 28 == 0) { n +=  4; i <<=  4; }
        if (i >>> 30 == 0) { n +=  2; i <<=  2; }
        n -= i >>> 31;//分析二
        return n;
    }

方法功能

该方法的作用是返回无符号整型i的最高非零位前面的0的个数,包括符号位在内;
如果i为负数,这个方法将会返回0,符号位为1.
比如说,10的二进制表示为 0000 0000 0000 0000 0000 0000 0000 1010
java的整型长度为32位。那么这个方法返回的就是28

分析

1.这一系列的判断,实际上是二分法的应用。
这里有一个比较巧妙的实现就是如果判断成立,那么成立之后会对i进行移位操作。
实际上就是因为条件成立,所以非零位在低16位,为方便后面处理(后面都是判断的高16位),将低16位左移到高16位位置。
2.分析二的位置实际上就是二分法对最后两个数的判断。n初始化为1,因此,如果判断最后的位为1,那么就减少一个n的数,否则为i>>>31为0的话,那么就不操作(n原先有一个1)

方法的实现分为下面几个步骤

1.判断整型i的值是否为0,如果是,那么表明0的个数为32个,直接返回即可
2.判断i无符号右移16位后的值是否为0.判断的是高16位的第一个非0数字是否存在。
条件成立,则表明第一个非0位在低16位
否则,第一个非零值在高16位。
3.如果前面的判断条件成立,(i>>>16 == 0) 那么进入if里面的语句之后,会将i向左移,将低16位变成高16位,对低16位进行计数。
如果判断不成立,即使非零位在高16为那么就没有必要进行移位的处理
4.后面的判断与第一个类似。

实例

比如一个数:0100 0010 0000 0010 0000 000
右移16位后


右移16位

结果为:


原先的高16位.png

因此,对于该数,判断条件 i>>>16==0 不成立,条件成立表明第一个非零数位于高16位。
此时的n=1

 if (i >>> 24 == 0)
右移后判断.png

得到一个全0的数,条件成立,进入if结构块,n=9
然后i进行左移8位的操作,把0100 0010 移动到最高位,此时
i = 0100 0010 0000 0010 0000 0000 0000 0000

其他

该方法实际上是一种二分法,不断的从中间的位置向左计算0的个数。如果左边都为0,那么就把右边的数移动左边,以此计算右边零的个数。
这个方法的实现可读性有点差。

上一篇 下一篇

猜你喜欢

热点阅读