int中使用的计数位数

sig*_*sen 4 java math binary bit-manipulation

如果你有二进制数10110我怎么能让它返回5?例如,一个数字告诉我们使用了多少位?下面列出了一些类似的例子:

  • 101应该返回3
  • 000000011应该返回2
  • 11100应该返回5
  • 101010101应该返回9

如何在Java中获得最简单的方法?我已经提出了以下方法,但我可以更快地完成:

public static int getBitLength(int value)
{
    if (value == 0)
    {
        return 0;
    }
    int l = 1;
    if (value >>> 16 > 0) { value >>= 16; l += 16; }
    if (value >>> 8 > 0) { value >>= 8; l += 8; }
    if (value >>> 4 > 0) { value >>= 4; l += 4; }
    if (value >>> 2 > 0) { value >>= 2; l += 2; }
    if (value >>> 1 > 0) { value >>= 1; l += 1; }
    return l;
}
Run Code Online (Sandbox Code Playgroud)

mer*_*ike 11

最简单的?

32 - Integer.numberOfLeadingZeros(value)
Run Code Online (Sandbox Code Playgroud)

如果您正在寻找算法,Java API的实现者会同意您的分而治之的位移方法:

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;
}
Run Code Online (Sandbox Code Playgroud)

编辑:提醒那些信任浮点计算准确性的人,运行以下测试工具:

public static void main(String[] args) {
    for (int i = 0; i < 64; i++) {
        long x = 1L << i;
        check(x);
        check(x-1);
    }
}

static void check(long x) {
    int correct = 64 - Long.numberOfLeadingZeros(x);
    int floated = (int) (1 + Math.floor(Math.log(x) / Math.log(2)));
    if (floated != correct) {
        System.out.println(Long.toString(x, 16) + " " + correct + " " + floated);
    }
}
Run Code Online (Sandbox Code Playgroud)

第一个检测到的偏差是:

ffffffffffff 48 49
Run Code Online (Sandbox Code Playgroud)


sta*_*lue 6

不幸的是,没有Integer.bitLength()方法可以直接给你答案.

存在类似的方法BigInteger,所以你可以使用那个:

BigInteger.valueOf(value).bitLength()
Run Code Online (Sandbox Code Playgroud)

构造BigInteger对象会使效率降低一些,但这只会影响数百万次.