条件运算符如何使用按位运算符表示?
这是一个家庭作业问题,我必须仅使用按位运算来实现条件运算符。如果允许
if
语句,那就很简单,但它必须是严格的按位运算符。
只能使用运算符
!
、~
、&
、^
、|
、+
、>>
和 <<
》。不能使用 if
语句或循环。
该函数需要三个整数,其工作方式与普通条件运算符类似。第一个参数被评估为零或非零。如果第一个参数为零,则返回第二个参数。如果第一个参数非零,则返回第三个参数。
我希望有一个简单的算法可以解决这个问题。任何关于从哪里开始的想法都会有很大的帮助。
是否允许使用移位作为按位运算符?允许算术运算符吗?
您的编辑并不完全清楚,但我认为您需要实现等效的
a ? b : c
其中
a
、b
和 c
是整数。这又相当于
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)
完成。
基本上不是。条件运算符将仅计算第二个或第三个操作数中的one;位运算符总是计算两个操作数。
我认为从按位运算符开始考虑条件运算符确实没有意义......例如,如果第二个和第三个操作数是指针类型,您就不会想考虑那些 在按位运算方面,你会吗?将条件运算符与按位运算符分开对待 - 尝试合并它们不会给自己带来任何好处。
我认为OP正在寻找一种方法来表达通常需要无分支方式条件的事物。例如(假设
unsigned x,y,z;
和 x
以 INT_MAX
为界):
if (x>2) y+=z;
可表示为:
y += z & -(2-x >> sizeof(unsigned)*CHAR_BIT-1);
我之所以想到这个例子,是因为我曾多次在“无分支二进制排序”中使用它。当被搜索的数组的大小恒定时,这允许将搜索循环完全展开为一系列没有分支的操作,并且每步仅编译为几个操作码。那些反对编写“C 汇编程序”的人可能更喜欢这样写:
y += (x>2) ? z : 0;
并希望编译器生成等效的位掩码或
cmov
指令。 :-)
如果您指的是三元选择运算符,则可以使用按位运算来表示,但仅限于某些情况(实际上,在某些情况下使用按位运算是一种优化)。例如:
(getsomevalue() == 1) ? somepointer : NULL;
可以表示为 somepointer & ~((unsigned)(getsomevalue()) - 1);
假设 getsomevalue()
仅返回 1 或 0(又名 BOOL)
这是一篇旧帖子,但当我为我的班级分配类似的作业时,我发现了它。这篇文章中的答案使用了太多的运算符来满足要求(最多 16 个运算符)。然而,在概念上仍然很有帮助。
这是我最终找到的解决方案:
一个?乙:丙
x = a >> 31; //如果为正则为 00...00 如果为负则为 11...11
y = (~a + 1) >> 31; //如果为正,则为 11...11;如果为负,则为 00...00
//如果 a 为零,则 x 和 y 都应该为 0,因为 y def 中的+1
z = x |是;
解决方案 (z 和 b) | (~z & c);
这是利用 C 中的移位是算术而非逻辑这一事实。
在最基本的层面上,它变成了电子产品。请参阅这个。我想不出任何其他应用程序来回答你的问题。