简体   繁体   English

使用少于5个按位运算符实现“逻辑非”

[英]Implementing “logical not” using less than 5 bitwise operators

As part of my CS classes I've recently completed the pretty popular "Data Lab" assignments. 作为我的CS课程的一部分,我最近完成了非常受欢迎的“数据实验室”任务。 In these assignments you are supposed to implement simple binary operations in C with as few operations as possible. 在这些分配中,您应该使用尽可能少的操作在C中实现简单的二进制操作。

For those who are not familiar with the "Data Lab" a quick overview about the rules: 对于那些不熟悉“数据实验室”的人,可以快速了解规则:

  • You may not call functions, cast or use control structures (eg if) 您不能调用函数,强制转换或使用控制结构(例如,如果)
  • You may assign variables with no operator cost, however only int is allowed) 您可以分配没有运营商成本的变量,但只允许使用int)
  • The less operators you use, the better 您使用的运营商越少越好
  • You may assume sizeof(int) == 32 您可以假设sizeof(int)== 32
  • Negative numbers are represented in 2's complement 负数用2的补码表示

The task is to implement a logical not called 'bang' (where bang(x) returns !x) by only using the following operators: ~ & ^ | 任务是通过仅使用以下运算符来实现一个不称为'bang'的逻辑(其中bang(x)返回!x):〜&^ | + << >> + << >>

The function prototype is defined as 函数原型定义为

int bang(int x)

The best implementation I could find (using 5 operators) was the following: 我能找到的最佳实现(使用5个运算符)如下:

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

However there seems to be a way to accomplish this with even less operators, since I found a result website[1] from some German university where two people apparently found a solution with less than 5 operator. 然而,似乎有一种方法可以通过更少的操作员来实现这一目标,因为我在一些德国大学找到了一个结果网站[1],其中两个人显然找到了一个少于5个操作员的解决方案。 But I can't seem to figure out how they accomplished that. 但我似乎无法弄清楚他们是如何完成的。

[1] http://rtsys.informatik.uni-kiel.de/~rt-teach/ss09/v-sysinf2/dlcontest.html (logicalNeg column) [1] http://rtsys.informatik.uni-kiel.de/~rt-teach/ss09/v-sysinf2/dlcontest.html(logicalNeg专栏)

To clarify: This is not about how to solve the issue, but how to solve it with less operations. 澄清:这不是关于如何解决问题,而是如何用较少的操作来解决问题。

Only slightly cheating: 只是轻微作弊:

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

is the only way I can think of to do it in only 3 operations. 是我能想到的只有3个操作的唯一方法。 Assumes a 32-bit int and 64-bit long... 假设32位int和64位长...

If you take the liberty of assuming that int addition overflow is well-defined and wraps (rather than being undefined behavior), then there's a solution with four operators: 如果您冒昧地假设int加法溢出是明确定义并且包装(而不是未定义的行为),那么有一个包含四个运算符的解决方案:

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

I think you are assuming that overflow is defined to wrap otherwise your function ((x | (~x + 1)) >> 31) + 1 has undefined behavior for x=INT_MIN. 我认为你假设溢出被定义为包装,否则你的函数((x | (~x + 1)) >> 31) + 1具有x = INT_MIN的未定义行为。

why not just :- 为什么不呢: -

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM