So I see that this question has already been asked, however the answers were a little vague and unhelpful. Okay, I need to implement a c expression using only "& ^ ~ ! + | >> <<"
The expression needs to resemble: a ? b : c
So, from what I've been able to tell, the expression needs to look something like:
return (a & b) | (~a & c)
This works when a = 0, because anding it with b will give zero, and then the or expression will return the right side, (~a & c)
which works because ~0 gives all ones, and anding c with all ones returns c.
However, this doesn't work when a > 0. Can someone try to explain why this is, or how to fix it?
I would convert a
to a boolean using !!a
, to get 0 or 1. x = !!a
.
Then I'd negate that in two's complement. Since you don't have unary minus available, you use the definition of 2's complement negation: invert the bits, then add one: y = ~x + 1
. That will give either all bits clear, or all bits set.
Then I'd and
that directly with one variable y & b
, its inverse with the other: ~y & c
. That will give a 0 for one of the expressions, and the original variable for the other. When we or
those together, the zero will have no effect, so we'll get the original variable, unchanged.
y = ~x + 1
part got me confused; I finally figured it works due to integer overflow in case when x = 0, but it's not obvious.
The more clear solution for me was to first shift lsb to msb with left shift (00000001 => 10000000) and then copy msb with right shift:
y = (x << 31) >> 31
Anton Sergeyev 2017-09-04 20:48
In other words, you need a
to have all bits set to 0, if a is false
(i.e. 0), and have all bits set to 1, if a
is true (i.e. a > 0
).
For the former case, the work is already done for you; for the latter -- try to work out result of the expression ~!1
.