13

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

在我继续之前,这是一个家庭作业问题,我已经坚持了很长时间。

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

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

例如:

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

6 回答 6

9

假设一个 32 位无符号整数:

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

应该做的伎俩

于 2011-02-11T16:53:32.113 回答
8

假设x是有符号的,任何非零的数字都需要返回 0,零则需要返回 1。

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

执行:

int bang(int x) {
    return ((x >> 31) | ((~x + 1) >> 31)) + 1;
}
于 2015-02-04T03:17:46.933 回答
1

以下代码将任何 1 位复制到所有位置。这会将所有非零值映射到,同时0xFFFFFFFF == -1离开。然后它加1,映射到和。00-1001

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
于 2011-02-06T09:23:22.843 回答
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.
于 2011-02-11T19:30:48.857 回答
0

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

~(((x >> 0) & 1)
| ((x >> 1) & 1) 
| ((x >> 2) & 1)
...
| ((x >> 7) & 1)) & 1
于 2011-01-21T23:40:16.290 回答
-3

You can just do ~x & 1 because it yields 1 for 0 and 0 for everything else

于 2011-02-11T16:20:03.213 回答