【问题标题】:Conditional Using Bitwise Operators使用位运算符的条件
【发布时间】:2010-09-26 16:03:26
【问题描述】:

条件运算符如何用位运算符表示?

这是一个作业问题,我必须仅使用按位运算来实现条件运算符。如果允许if 语句会很简单,但它必须是严格的位运算符。

只能使用运算符!~&^|+>><<。不能使用if 语句或循环。

该函数采用三个整数,其工作方式与普通条件运算符一样。第一个参数被评估为零或非零。如果第一个参数为零,则返回第二个参数。如果第一个参数不为零,则返回第三个参数。

我希望有一个简单的算法来解决这个问题。任何关于从哪里开始的想法都会有很大帮助。

【问题讨论】:

  • 您能说得更具体些吗?这听起来像是一个措辞不好的家庭作业问题。我不知道用另一个操作员“代表”一个操作员是什么意思。
  • 在 C 术语中,术语 条件运算符 表示三元 ?: 运算符。该运算符不是也不能由位运算符以任何有意义的方式表示。如前所述,您的问题几乎没有(如果有的话)意义。请澄清一下。
  • 您的运算符的结果应该如何取决于第一个 int?只是简单的零/非零检查,还是其他?
  • 零/非零检查是我需要做的,但我不能使用任何 if 语句。
  • 抱歉,“不能使用 if 语句”和“只能使用按位运算符”之间有天壤之别。那么,它是什么?

标签: c bit-manipulation


【解决方案1】:

是否允许移位作为按位运算符?是否允许算术运算符?

您的编辑并不完全清楚,但我认为您需要实现等效的

a ? b : c

其中abc 是整数。这又相当于

a != 0 ? b : c

实现这一点的一种方法是找到一种方法,将a 的非零值转换为仅使用位运算符的全1 位模式。如果我们弄清楚如何做到这一点,剩下的就很容易了。现在,我不会立即记住任何可以做到这一点的巧妙技巧(我相信它们确实存在),而且我不确定哪些运算符是允许的,哪些是不允许的,所以现在我将使用类似

a |= a >> 1; a |= a >> 2; a |= a >> 4; a |= a >> 8; a |= a >> 16;
a |= a << 1; a |= a << 2; a |= a << 4; a |= a << 8; a |= a << 16;

对于 32 位整数类型,如果(且仅当)在原始 a 中设置了至少一个位,上述结果应该导致 a 的所有位都设置为 1。(假设我们正在使用无符号整数,以避免与有符号值移位相关的问题)。同样,我敢肯定,必须有更聪明的方法来做到这一点。例如:a = !a - 1,但不知道!-是否允许。

一旦我们这样做了,原来的条件运算符就变成了

(a & b) | (~a & c)

完成。

【讨论】:

  • 要制作一个全为位模式,我可以使用:a = !a;一个=〜一个。如果 a 为零怎么办?
  • @Matt:我不明白。 a = !a; a = ~a 是什么?首先,! 不是位运算符。你能用吗?其次,重点是在全1位模式中将非零a变为非零a保持不变(即全零位模式)。
  • 我没有意识到这会将非零 a 更改为全为位模式,而单独留下零 a。这完美地工作。非常感谢!
  • @Matt — ~a 不会将非零 a 更改为全一的位模式;相反,它所做的是将0x00000001 映射到0xFFFFFFFE。你想要的是-a,它将0x00000000 映射到0x00000000 并将0x00000001 映射到0xFFFFFFFF
【解决方案2】:

基本上不是。条件运算符只会计算第二个或第三个操作数中的一个;位运算符总是计算两个操作数。

我认为从位运算符的角度来考虑条件运算符是没有意义的......例如,如果第二个和第三个操作数是指针类型,你就不会想那些按位运算,你会吗?将条件运算符与位运算符分开处理 - 尝试合并它们不会给自己带来任何好处。

【讨论】:

  • 这里必须同意第二段。最好从它们在机器层面所做的事情来考虑它们,而不是试图将它们与另一个相关联。
【解决方案3】:

我认为 OP 正在寻找一种方法来表达通常需要以无分支方式使用条件的事物。例如(假设unsigned x,y,z;xINT_MAX 为界):

if (x>2) y+=z;

可以表示为:

y += z & -(2-x >> sizeof(unsigned)*CHAR_BIT-1);

之所以想到这个例子,是因为我曾多次在“无分支二进制排序”中使用它。当要搜索的数组的大小是恒定的时,这允许将搜索循环完全展开为一系列没有分支的操作​​,并且每步只编译几个操作码。那些反对编写“C 汇编程序”的人可能更喜欢这样写:

y += (x>2) ? z : 0;

并希望编译器生成等效的位掩码或cmov 指令。 :-)

【讨论】:

    【解决方案4】:

    如果您指的是三元选择运算符,则可以使用按位运算来表示,但仅在某些情况下(实际上它是在某些情况下使用按位运算的优化)。例如:(getsomevalue() == 1) ? somepointer : NULL; 可以表示为 somepointer &amp; ~((unsigned)(getsomevalue()) - 1); 假设 getsomevalue() 只返回 1 或 0(又名 BOOL)

    【讨论】:

      【解决方案5】:

      在最基本的层面上,它变成了电子产品。见this。对于您的问题,我想不出任何其他应用程序。

      【讨论】:

        猜你喜欢
        • 2012-04-19
        • 1970-01-01
        • 2023-04-05
        • 2012-12-05
        • 2016-11-20
        • 2013-03-13
        • 2012-04-19
        • 2012-01-20
        • 1970-01-01
        相关资源
        最近更新 更多