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个数。