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

发布于 2024-10-13 00:32:00 字数 318 浏览 4 评论 0原文

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

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

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

郑重声明:我也不能使用条件、循环、== 等,只能使用我上面提到的函数(按位)。

例如:

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

~ & ^ | + << >> are the only operations I can use

Before I continue, this is a homework question, I've been stuck on this for a really long time.

My original approach: I thought that !x could be done with two's complement and doing something with it's additive inverse. I know that an xor is probably in here but I'm really at a loss how to approach this.

For the record: I also cannot use conditionals, loops, ==, etc, only the functions (bitwise) I mentioned above.

For example:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

栀子花开つ 2024-10-20 00:32:00

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

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

应该可以解决问题

Assuming a 32 bit unsigned int:

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

should do the trick

他是夢罘是命 2024-10-20 00:32:00

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

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

执行:

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

Assuming x is signed, need to return 0 for any number not zero, and 1 for zero.

A right shift on a signed integer usually is an arithmetical shift in most implementations (e.g. the sign bit is copied over). Therefore right shift x by 31 and its negation by 31. One of those two will be a negative number and so right shifted by 31 will be 0xFFFFFFFF (of course if x = 0 then the right shift will produce 0x0 which is what you want). You don't know if x or its negation is the negative number so just 'or' them together and you will get what you want. Next add 1 and your good.

implementation:

int bang(int x) {
    return ((x >> 31) | ((~x + 1) >> 31)) + 1;
}
一向肩并 2024-10-20 00:32:00

以下代码将任意 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

The following code copies any 1 bit to all positions. This maps all non-zeroes to 0xFFFFFFFF == -1, while leaving 0 at 0. Then it adds 1, mapping -1 to 0 and 0 to 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
你丑哭了我 2024-10-20 00:32:00

对于 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.

For 32 bit signed integer 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.
梦回旧景 2024-10-20 00:32:00

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

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

Assuming e.g. an 8-bit unsigned type:

~(((x >> 0) & 1)
| ((x >> 1) & 1) 
| ((x >> 2) & 1)
...
| ((x >> 7) & 1)) & 1
思念满溢 2024-10-20 00:32:00

你可以做 ~x & 1 因为它对于 0 产生 1,对于其他一切产生 0

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文