有条件地使用按位运算符

发布于 2024-09-25 03:35:45 字数 429 浏览 3 评论 0原文

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

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

仅运算符 !~&^|、<可以使用 code>+、>><<。不能使用 if 语句或循环。

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

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

How is the conditional operator represented using bitwise operators?

It is a homework question where I have to implement the conditional operator using only bitwise operations. It would be simple if if statements were allowed, however it has to be strictly bitwise operators.

Only the operators !, ~, &, ^, |, +, >>, and << can be used. No if statements or loops can be used.

The function takes three ints and works just like the normal conditional operator. The first argument is evaluated as either zero or non-zero. If the first argument is zero then the second argument is returned. If the first argument is non-zero then the third argument is returned.

I was hoping there would be a simple algorithm for this. Any ideas on where to start would be a great help.

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

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

发布评论

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

评论(6

无声情话 2024-10-02 03:35:45

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

您的编辑并不完全清楚,但我假设您需要实现

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;

For 32 位整数类型,如果(且仅当)原始 a 中至少设置了一位,则上述结果应将 a 的所有位设置为1.(假设我们正在使用无符号整数,以避免与有符号值移位相关的问题)。我再次确信,一定有一种更聪明的方法来做到这一点。例如:a = !a - 1,但我不知道!-是否允许。

一旦我们完成了这个操作,原来的条件运算符就相当于

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

Done。

Are shifts allowed as bitwise operators? Are arithmetic operators allowed?

Your edit is not entirely clear, but I assume that you need to implement an equivalent of

a ? b : c

where a, b and c are integers. This is in turn equivalent to

a != 0 ? b : c

One way to achieve that is to find a way to turn non-zero value of a into an all-ones bit pattern using only bitwise operators. If we figure out how to do that, the rest would be easy. Now, I don't immediately remember any ingenious tricks that would do that (they do exist I believe), and I don't know for sure which operators are allowed and which are not, so for now I will just use something like

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;

For a 32-bit integer type, if (and only if) there was at least one bit set in the original a, the above should result in all bits of a set to 1. (Let's assume we are working with unsigned integers, to avoid the issues associated with shifting of signed values). Again, there must be a more clever way to do that, I'm sure. For example: a = !a - 1, but I don't know if ! and - are allowed.

Once we've done that, the original conditional operator becomes equivalent to

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

Done.

隔纱相望 2024-10-02 03:35:45

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

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

It's not, basically. The conditional operator will only evaluate one of the second or third operands; bitwise operators always evaluate both operands.

I don't think it really makes sense to think of the conditional operator in terms of bitwise operators to start with... for example, if the second and third operands are pointer types, you wouldn't want to think of those in terms of bitwise ops, would you? Treat the conditional operator separately to the bitwise operators - you won't do yourself any favours by trying to amalgamate them.

飘逸的'云 2024-10-02 03:35:45

我认为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 指令。 :-)

I think the OP is looking for a way to express things which would normally require a conditional in a branchless way. For instance (assuming unsigned x,y,z; and x is bounded by INT_MAX):

if (x>2) y+=z;

can be expressed as:

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

This example comes to mind because I've used it in a "branchless binary sort" on a number of occasions. When the size of the array being searched is constant, this allows completely unrolling the search loop into a sequence of operations with no branches, and compiles to just a few opcodes per step. Those who object to writing "assembler in C" might prefer it to be written:

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

and hope the compiler generates an equivalent bit mask or cmov instruction. :-)

南汐寒笙箫 2024-10-02 03:35:45

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

If your refering to the ternary selection operator, this can be represented using bitwise operations, but only in certain cases(in fact its an optimization to use bitwise ops in some cases). Eg: (getsomevalue() == 1) ? somepointer : NULL; can be represented as somepointer & ~((unsigned)(getsomevalue()) - 1); assuming getsomevalue() only returns 1 or 0(aka BOOL)

独自唱情﹋歌 2024-10-02 03:35:45

这是一篇旧帖子,但当我在课堂上收到类似的作业时,我发现了它。这篇文章中的答案使用了太多的运算符来满足要求(最多 16 个运算符)。然而,在概念上仍然有帮助。

这是我最终找到的解决方案:

a ? b : c

x = a>> 31; //如果为正则得到 00...00 如果为负则得到 11...11

y = (~a + 1) >>> 31; //如果为正,则为 11...11;如果为负,则为 00...00

//如果 a 为零,则 x 和 y 都应为 0,因为 y 中的 +1 def

z = x | y;

解决方案
(z 和 b) | (~z & c);

这是利用 C 中的移位是算术而非逻辑这一事实。

This is an old post, but I came across it when I got a similar assignment for my class. The answer in this post used too many operators for the requirement (max 16 operators). However, was still helpful conceptually.

Here is the solution I ended up finding:

a ? b : c

x = a >> 31; //this gets 00...00 if positive 11...11 if negative

y = (~a + 1) >> 31; //this gets 11...11 if positive 00...00 if negative

//if a is zero both x and y should be 0 because of the +1 in y def

z = x | y;

solution
(z & b) | (~z & c);

This is using the fact that shifts in C are arithmetic, not logical.

这样的小城市 2024-10-02 03:35:45

在最基本的层面上,它变成了电子产品。请参阅。我想不出您的问题有任何其他应用。

At the very basic level it becomes electronics. See this. I cannot think of any other application for your question.

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