我已经考虑过这个问题好几个小时了,但解决方案并不想来。也许有人有任何想法?
问题是:
"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,但为了简单起见,请将其作为二进制,它仅仅是细节。
答案 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