Reputation: 3689
Is there a way to get a result of applying a ternary ?:
operator to individual bits without actually computing it one bit at a time, i.e. using some combination of and-s, or-s, xor-s, and not-s?
In other words, given we have 3 int
s (regardless of bit length): a
, b
, and mask m
, the result r
should basically be: r = m ? a : b
, except on a per-bit basis.
Assuming a = 0b0101; b = 0b1110;
and m = 0b0110
, the result r
should be 0b1100
. So, if bit n in mask m
is 1
(true), use the n-th bit from a
; otherwise (if bit n in mask m
is 0
(false)) then use the n-th bit from b
.
Upvotes: 1
Views: 237
Reputation: 3689
For explanatory purposes, I soon realized that the problem can be thought of as taking all valid 1
s from a
and b
by using the mask m
and combining the results. Then the problem becomes trivial, as illustrated in the truth table:
-------------------------------------------
a: 0 0 0 0 1 1 1 1
b: 1 1 0 0 1 1 0 0
m: 1 0 1 0 1 0 1 0 // 1 = the positions from a; 0 = positions from b
~m: 0 1 0 1 0 1 0 1
x = m & a: 0 0 0 0 1 0 1 0 // take all valid 1s from a
y = ~m & b: 0 1 0 0 0 1 0 0 // take all valid 1s from b
r = x | y: 0 1 0 0 1 1 1 0 // combine: r = (m & a) | (~m & b)
-------------------------------------------
EXPECTED: 0 1 0 0 1 1 1 0
An alternative implementation using xor-s: r = b ^ (m & (a ^ b))
-------------------------------------------
a: 0 0 0 0 1 1 1 1
b: 1 1 0 0 1 1 0 0
m: 1 0 1 0 1 0 1 0 // 1 = the positions from a; 0 = positions from b
u = a ^ b: 1 1 0 0 0 0 1 1
v = m & u: 1 0 0 0 0 0 1 0
r = b ^ v: 0 1 0 0 1 1 1 0
-------------------------------------------
EXPECTED: 0 1 0 0 1 1 1 0
Upvotes: 0
Reputation: 15525
If m
, a
and b
are all guaranteed to be 0 or 1, then m ? a : b
is equivalent to (m && a) || (!m && b)
. You can see that by injecting m=0
or m=1
in the formula and simplifying it.
This works bitwise too; bitwise not is usually noted ~
; so the "bitwise ternary operator" that you are looking for can be expressed as:
(m&a)|((~m)&b)
Upvotes: 1