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?
答案 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位这为我们提供了答案顶部的代码。
<强>测试强>
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位的位置索引