按位运算逻辑任务

时间:2013-07-27 09:40:17

标签: bit-manipulation bitwise-operators bit

我已经考虑过这个问题好几个小时了,但解决方案并不想来。也许有人有任何想法?

问题是:

 "Using ONLY bitwise operators, write the function that sets 
  the leftmost zero bit to one" 

Conditions - prohibited
Recursion - prohibited
Loops - prohibited
Arithmetic operations - prohibited

示例:

输入:11010010

输出:11110010

P.S。输入实际上应该是unsigned int,但为了简单起见,请将其作为二进制,它仅仅是细节。

3 个答案:

答案 0 :(得分:2)

你可以像这样将最左边的零传播到右边:

x &= x >> 1;
x &= x >> 2;
x &= x >> 4;
// etc

在示例中,您将获得11000000

然后,如果你反转它,你得到一个掩码,包括最左边的零,在这个例子中,00111111

然后你可以通过x ^ (x >> 1)

轻松地隔离最左边的那个(通过构造,与输入中最左边的零位于同一位置)

将OR输入到输入中。

把它放在一起:(未经测试)

uint32_t y = x;
x &= x >> 1;
x &= x >> 2;
x &= x >> 4;
x &= x >> 8;
x &= x >> 16;
x = ~x;
return y | (x ^ (x >> 1));

可能有一个更简单的解决方案

答案 1 :(得分:0)

经过一段时间后出现了与harold建议类似的解决方案,但几乎没有什么改进。 这是代码

unsigned long int getLastZeroPosition(unsigned long int value)
{
   unsigned long int temp = ~value;
   temp = temp | temp >> 1;
   temp = temp | temp >> 2;
   temp = temp | temp >> 4;
   temp = temp | temp >> 8;
   temp = temp | temp >> 16;
   temp = temp | temp >> (sizeof(unsigned long int) << 2);  // handles x86/x64

   temp = temp >> 1;
   temp = (~temp) & (~value);
   return temp;
}

答案 2 :(得分:0)

我将假设我可以使用Java实现。 如果您将问题更改为“仅使用按位运算符,编写将 RIGHTMOST 零位设置为1”的函数,则可以按如下方式解决问题:

int a = 0b1111_1111_1111_1111_1111_1101_0110_1111;
a = a | (a & (a^(a+1)))+1;
System.out.println(Integer.toBinaryString(a));

这个答案是我们需要的镜像,所以只需先反映输入:

int a = 0b1111_1111_1111_1111_1111_1101_0110_1111;
a = Integer.reverse(a);
a = Integer.reverse(a | (a & (a ^ (a + 1))) + 1);
System.out.println(Integer.toBinaryString(a));

但是,当然,使用一个内置的Java(reverse),您也可以使用另一个(highestOneBit):

int a = 0b1111_1111_1111_1111_1111_1101_0110_1111;
a = Integer.highestOneBit(~a)+a;
System.out.println(Integer.toBinaryString(a));

如果您想使用基本的按位运算符实现自己的reverse,并且可能在c中实现,那么这也是可能的:Reverse bits