numberOfTrailingZeros函数和numberOfLeadingZeros函数

numberOfTrailingZeros

代码如下:

/**
     * Returns the number of zero bits following the lowest-order ("rightmost")
     * one-bit in the two's complement binary representation of the specified
     * {@code long} value.  Returns 64 if the specified value has no
     * one-bits in its two's complement representation, in other words if it is
     * equal to zero.
     *
     * @param i the value whose number of trailing zeros is to be computed
     * @return the number of zero bits following the lowest-order ("rightmost")
     *     one-bit in the two's complement binary representation of the
     *     specified {@code long} value, or 64 if the value is equal
     *     to zero.
     * @since 1.5
     */
    public static int numberOfTrailingZeros(long i) {
        // HD, Figure 5-14
        int x, y;
        if (i == 0) return 64;
        int n = 63;
        y = (int)i; if (y != 0) { n = n -32; x = y; } else x = (int)(i>>>32);
        y = x <<16; if (y != 0) { n = n -16; x = y; }
        y = x << 8; if (y != 0) { n = n - 8; x = y; }
        y = x << 4; if (y != 0) { n = n - 4; x = y; }
        y = x << 2; if (y != 0) { n = n - 2; x = y; }
        return n - ((x << 1) >>> 31);
    }

这个函数用来获取long类型数值从低位开始连续0的个数,例如:

00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001

也就是1执行完Long.numberOfTrailingZeros(1)函数后值为0,同样:

00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000010

值为1,

现在我们开始分析代码,这里首先如果i为0,此时所有bit都为0,所以值为64

如果i不为0,说明此时最大的连续0个数为63(此时值为10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000),所以这里设置n为63,从63开始计算。

下面进入到代码

 y = (int)i; if (y != 0) { n = n -32; x = y; } else x = (int)(i>>>32);
 y = x <<16; if (y != 0) { n = n -16; x = y; }
 y = x << 8; if (y != 0) { n = n - 8; x = y; }
 y = x << 4; if (y != 0) { n = n - 4; x = y; }
 y = x << 2; if (y != 0) { n = n - 2; x = y; }
return n - ((x << 1) >>> 31);

这里主要的思路就是采用二分法,也就是先分析低32位,

如果不为0,说明低32位中存在某一个bit为1,也就是说连续为0的个数小于32,然后继续采用二分法,判断低16位,依次类推

如果为0,说明低32位所有bit都为0,应该统计高32位中的从低位到高位连续的0个数,然后将高位连续为0个数加上32就是该long型变量从低位到高位连续为0的个数。

如此推导下来

最终需要判断的位就剩下2位了,然后开始执行n - ((x << 1) >>> 31),如果剩下的两位从高到低的第一位为1,那么此时函数返回值就为n - 0=n,如果剩下的两位从高到低第二位为1,那么就为n - 1。

numberOfLeadingZeros函数

这个函数用来获取long类型数值从高位开始连续0的个数

代码如下:

/**
     * Returns the number of zero bits preceding the highest-order
     * ("leftmost") one-bit in the two's complement binary representation
     * of the specified {@code long} value.  Returns 64 if the
     * specified value has no one-bits in its two's complement representation,
     * in other words if it is equal to zero.
     *
     * <p>Note that this method is closely related to the logarithm base 2.
     * For all positive {@code long} values x:
     * <ul>
     * <li>floor(log<sub>2</sub>(x)) = {@code 63 - numberOfLeadingZeros(x)}
     * <li>ceil(log<sub>2</sub>(x)) = {@code 64 - numberOfLeadingZeros(x - 1)}
     * </ul>
     *
     * @param i the value whose number of leading zeros is to be computed
     * @return the number of zero bits preceding the highest-order
     *     ("leftmost") one-bit in the two's complement binary representation
     *     of the specified {@code long} value, or 64 if the value
     *     is equal to zero.
     * @since 1.5
     */
    public static int numberOfLeadingZeros(long i) {
        // HD, Figure 5-6
         if (i == 0)
            return 64;
        int n = 1;
        int x = (int)(i >>> 32);
        if (x == 0) { n += 32; x = (int)i; }
        if (x >>> 16 == 0) { n += 16; x <<= 16; }
        if (x >>> 24 == 0) { n +=  8; x <<=  8; }
        if (x >>> 28 == 0) { n +=  4; x <<=  4; }
        if (x >>> 30 == 0) { n +=  2; x <<=  2; }
        n -= x >>> 31;
        return n;
    }

该函数的原理和numberOfTrailingZeros函数类似,只不过numberOfTrailingZeros是从低到高位连续0个数,numberOfLeadingZeros是从高到低位连续0个数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值