get position of leftmost 0 bit of a number

时间:2017-05-16 09:21:05

标签: java bitwise-operators

I'm trying to get the leftmost position of number 0 of an integer

    int a = 83

For example, binary of 83 is 1010011 so we have have position of leftmost bit 0 is 6th. I wonder is there a way only using bitwise operator to find the answer?

3 个答案:

答案 0 :(得分:2)

<强> TL; DR

private static int leftmostZeroBit(int a) {
    int b = Integer.highestOneBit(a);
    return (b == 0 ? -1 : 31 - Integer.numberOfLeadingZeros(a ^ b ^ (b - 1)));
}

private static int leftmostZeroBit(long a) {
    long b = Long.highestOneBit(a);
    return (b == 0 ? -1 : 63 - Long.numberOfLeadingZeros(a ^ b ^ (b - 1)));
}

<强>解释

与通过位的简单搜索循环相比,不知道这是否有效,但您可以使用以下方法来帮助:
Integer.highestOneBit(int i)
Integer.numberOfLeadingZeros(int i)

它们每个都使用位操作,因此它们需要少于32次迭代(如果使用Long版本则需要64次迭代)。

给定1101011的示例输入值,我们希望将其反转为0010100

请记住,int有32位,所以左边有25个0位,所以要反转它,我们需要使用掩码1111111进行异或。

可以通过调用highestOneBit()来计算该掩码,这会给我们1000000,减去1给出0111111,并且组合它们会给出掩码。

一旦我们完成XOR并得到0010100,我们计算31 - numberOfLeadingZeros()以找到前导1位的位置,在此示例中为4。

然后我们可以定义我们希望结果为无效输入的-1

  • 000无效,因为没有最左边的0位而没有1位
  • 111无效,因为在1位
  • 之后没有0位

这为我们提供了答案顶部的代码。

<强>测试

public static void main(String[] args) {
    test(0x6B); // example in answer
    test(0x53); // example in question (83)
    test(0x29);
    test(0x14);
    test(0x0A);
    test(0x05);
    test(0x02);
    test(0x01);
    test(0x00);
    test(0x80000000);
    test(0xFFFFFFFE);
}
private static void test(int a) {
    System.out.printf("%32s: %d%n", Integer.toBinaryString(a), leftmostZeroBit(a));
}

<强>输出

                         1101011: 4
                         1010011: 5
                          101001: 4
                           10100: 3
                            1010: 2
                             101: 1
                              10: 0
                               1: -1
                               0: -1
10000000000000000000000000000000: 30
11111111111111111111111111111110: 0

答案 1 :(得分:0)

As far as I can understand you can use Bitwise operator but alone won't do it. You have to use Conditional Operator to get the output since program has to check the last occurrence of 0 from right to left or first occurrence of 0 from left to right.

答案 2 :(得分:0)

你可以这样做:

    int a = 83
    int mask = 1;
    // This loop finds the leftmost 1 bit
    while(a > mask) 
        mask <<= 1;
    mask >>= 1;
    // This loop starts from the leftmost 1 bit and searches for the first 0 going right
    while((a & mask) != 0) 
        mask >>= 1;

    System.out.println(Math.log(mask) / Math.log(2) + 1); // 6

最后一次记录&#34;必须给出最左边0位的位置索引