仅使用按位运算符实现逻辑否定(除了!)

时间:2011-01-21 23:34:32

标签: c bit-manipulation boolean-logic negation

~ & ^ | + << >>是我可以使用的唯一操作

在我继续之前,这是一个功课问题,我已经坚持了很长时间。

我原来的方法:我认为!x可以用两个补码完成,并用它的加法逆做一些事情。我知道xor可能在这里,但我真的不知道如何处理这个问题。

对于记录:我也不能使用条件,循环,==等,只能使用上面提到的函数(按位)。

例如:

!0 = 1
!1 = 0
!anything besides 0 = 0

6 个答案:

答案 0 :(得分:7)

假设32位无符号int:

(((x>>1) | (x&1)) + ~0U) >> 31

应该做的伎俩

答案 1 :(得分:4)

假设x已签名,则需要为任何不为零的数字返回0,并为零返回1。

有符号整数的右移通常是大多数实现中的算术移位(例如,符号位被复制)。因此,将x右移31,将其否定为31.其中一个将为负数,因此右移31将为0xFFFFFFFF(当然,如果x = 0,则右移将产生0x0,这是你想要什么)。你不知道x或它的否定是负数,所以只是&#39;或&#39;他们在一起,你会得到你想要的。接下来加1和你的好。

实现:

int bang(int x) {
    return ((x >> 31) | ((~x + 1) >> 31)) + 1;
}

答案 2 :(得分:1)

以下代码将任意1位复制到所有位置。这会将所有非零映射到0xFFFFFFFF == -1,同时将0保留在0。然后它添加1,将-1映射到0,将0映射到1

x = x | x << 1  | x >> 1
x = x | x << 2  | x >> 2
x = x | x << 4  | x >> 4
x = x | x << 8  | x >> 8
x = x | x << 16 | x >> 16

x = x + 1

答案 3 :(得分:1)

对于32位有符号整数x

// Set the bottom bit if any bit set.
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;

x ^= 1;   // Toggle the bottom bit - now 0 if any bit set.
x &= 1;   // Clear the unwanted bits to leave 0 or 1.

答案 4 :(得分:0)

假设,例如8位无符号类型:

~(((x >> 0) & 1)
| ((x >> 1) & 1) 
| ((x >> 2) & 1)
...
| ((x >> 7) & 1)) & 1

答案 5 :(得分:-3)

你可以做~x&amp; 1因为它为0而0为0,其他所有为0