使用少于 5 个按位运算符实现 "logical not"

Implementing "logical not" using less than 5 bitwise operators

作为我的 CS 类 的一部分,我最近完成了非常受欢迎的 "Data Lab" 作业。在这些作业中,您应该使用尽可能少的操作在 C 中实现简单的二进制操作。

对于那些不熟悉 "Data Lab" 规则的快速概述:

任务是通过仅使用以下运算符来实现逻辑不调用 'bang'(其中 bang(x) returns !x):~ & ^ | + << >>

函数原型定义为

int bang(int x)

我能找到的最佳实现(使用 5 个运算符)如下:

return ((x | (~x +1)) >> 31) + 1

然而,似乎有一种方法可以用更少的操作员来实现这一点,因为我从一些德国大学找到了一个结果网站[1],其中两个人显然找到了一个少于 5 个操作员的解决方案。但我似乎无法弄清楚他们是如何做到这一点的。

[1] http://rtsys.informatik.uni-kiel.de/~rt-teach/ss09/v-sysinf2/dlcontest.html(逻辑负列)

澄清一下:这里不是说如何解决问题,而是如何用更少的操作解决问题。

为什么不只是:-

int bang(int x)
{
    return 1 >> x;
}

只是轻微作弊:

int bang(int x) {
    return ((x ^ 0xffffffffU) + 1UL) >> 32;
}

是我能想到的唯一方法,只需 3 次操作即可完成。假设一个 32 位 int 和 64 位 long...

如果您冒昧地假设 int 加法溢出是明确定义的并包装(而不是未定义的行为),那么有一个包含四个运算符的解决方案:

((a | (a + 0x7fffffff)) >> 31) + 1

我认为您假设溢出被定义为换行,否则您的函数 ((x | (~x + 1)) >> 31) + 1 对于 x=INT_MIN.

具有未定义的行为