Question Details

No question body available.

Tags

c++ bitwise-operators

Answers (5)

Accepted Answer Available
Accepted Answer
December 28, 2025 Score: 18 Rep: 74,233 Quality: Expert Completeness: 50%

Your operation is multiplication, with A=0, B=1, C=-1.

A op A = A ->  0   0 =  0
A op B = A ->  0   1 =  0
A op C = A ->  0  -1 =  0
B op A = A ->  1   0 =  0
B op B = B ->  1   1 =  1
B op C = C ->  1  -1 = -1
C op A = A -> -1   0 =  0
C op B = C -> -1   1 = -1
C op C = B -> -1 * -1 =  1

But if you don't want to use that, you can use this:

A = 0b00
B = 0b01
C = 0b11

Tri op(Tri x, Tri y) { unsigned abit = (x & y) & 0b1; unsigned amask = (a_bit
December 27, 2025 Score: 12 Rep: 128,899 Quality: Expert Completeness: 100%

Your operator is symmetric, ie

x op y == y op x

Further, A op x == A for any x, otherwise if x == y then x op y == B and x op y == C if x != y.

Hence, the operator can be implemented as

unsigned op0(unsigned x,unsigned y) { if (x == A or y == A) return A; if (x == y) return B; return C; }

Once you choose values for A,B,C its just a matter of refactoring the above function to access and set individual bits. Here:

unsigned A = 0b00; unsigned B = 0b11; unsigned C = 0b01;

The first bit indicates whether the value is an A. The other bit distinguishes B, and C. Rewriting the above ifs in bit operations is straightforward:

  • x op y has the first bit set if x and y have the first bit set.
  • x op y has the second bit set if x and y have the first bit set and both have the second bit set or neither of them has it set (ie their second bit is equal).

For readability I use temporaries for the individual bits:

unsigned op(unsigned x,unsigned y) { bool x0 = 0b01 & x; bool x1 = 0b10 & x; bool y0 = 0b01 & y; bool y1 = 0b10 & y; return ((x0 and y0)>>0) | ((x1==y1 and x0 and y0)
December 29, 2025 Score: 6 Rep: 43,404 Quality: High Completeness: 100%

This answer shows a systematic approach to defining your operator for any arbitrary truth table, using K-Maps and using 2 bits to encode A, B, and C.

We'll (fairly arbitarily) assign:

  • A = 00
  • B = 01
  • C = 10

We can then take our truth table:

X Y O
A A A
A B A
A C A
B A A
B B B
B C C
C A A
C B C
C C C

And rewrite this in terms of the two bits we assigned to each letter. We use X to mean "Don't care".

Our notation is that, if X = 01 (i.e. it has the value B), then X1 = 0 and X2 = 1.

X1 X2 Y1 Y2 O1 O2
0 0 0 0 0 0
0 0 0 1 0 0
0 0 1 0 0 0
0 0 1 1 X X
0 1 0 0 0 0
0 1 0 1 0 1
0 1 1 0 1 0
0 1 1 1 X X
1 0 0 0 0 0
1 0 0 1 1 0
1 0 1 0 1 0
1 1 0 0 X X
1 1 0 1 X X
1 1 1 0 X X
1 1 1 1 X X

We can then construct K-maps for the two outputs O1 and O2, in terms of the 4 input bits X1, X2, Y1, and Y2. I'm not going to describe in detail how to do K-maps as that's rather a large topic (and Wikipedia does it pretty well), but I'll work this example so you can see it in practice.

O1:

This is the K-Map for O1 in terms of X1, X2, Y1 and Y2. I've marked the two fairly obvious groupings which describe when O1 is 1 (making use of the "don't care's"):

Here, the rows are values for the X input (so X1X2 = 01 means that X1 = 0 and X2 = 1, etc), and the columns are values for the Y input.

O1 K-Map

This gives:

O1 formula

O2:

This is the K-Map for O2 in terms of X1, X2, Y1 and Y2. Here the 1's are annoyingly dispirate and hard to group, so I'm going to group the 0's instead:

O2 K-Map

O2 formula

Then by De Morgan's laws:

O2 formula simplification


You can then implement this as e.g.:

auto op (auto x, auto y) {
    auto x1 = x & 0b01;
    auto x2 = (x & 0b10) >> 1;
    auto y1 = y & 0b01;
    auto y2 = (y & 0b10) >> 1;
    auto o1 = (x1 & y2) | (x2 & y1);
    auto o2 = (x1 | x2) & (y1 | y2);

return (o1
December 28, 2025 Score: 3 Rep: 4,935 Quality: Medium Completeness: 80%

In complement to Sebastian Redl's answer, it is possible to follow a SWAR approach and vectorize up to 32 operators within a std::uint64t register. The operator becomes:

template auto op (T x, T y) { T a
bit = (x & y) & 0x5555555555555555; T amask = (abit
December 30, 2025 Score: 0 Rep: 4,822 Quality: Low Completeness: 80%

Basically I come to the same conclusion as https://stackoverflow.com/a/79855949/6607497 does.

With "simplified C" and A == 0b001, B == 0x010, C == 0b100 the table is:

Op1 Op2 Result
001 001 001
001 010 001
001 100 001
010 001 001
010 010 010
010 100 100
100 001 001
100 010 100
100 100 010

Looking at the ones in the result, the result is A if any of the operands is A. (Else) The Result is B if both operands are either B or C (otherwise the result is C).

So the result would be

o1 == 0b001 || o2 == 0b001 ? 0b001 : o1 == o2 ? 0b010 : 0b100