1

I have a question: Is bitwise anding transitive, particularly in C and C++?

Say res=(1 & 2 & 3 & 4), is this same as res1=(1&2) and res2=(3&4) and res= (res1 & res2). Will this be same?

François Andrieux
  • 28,148
  • 6
  • 56
  • 87
Raj
  • 401
  • 6
  • 20
  • 2
    Note that there is no C/C++. There is some overlap between the two languages due to their common ancestry and that this is what C/C++ means, but that doesn't describe a language and this overlap is slowly shrinking as the language evolve and diverge. In this case C and C++ agree on the answer to your question. But there is no C/C++, C++ is not an extension of C and C is not a subset of C++. They are distinct languages. – François Andrieux Sep 25 '18 at 03:06
  • @FrançoisAndrieux There's currently an open discussion at meta regarding cross-tagging C and C++: https://meta.stackoverflow.com/questions/374306/proposed-update-to-c-and-c-tag-usage-wikis – Lundin Sep 25 '18 at 06:41
  • Note that in the C language, there is a whole lot of implicit type promotions going on behind the lines. This can have all manner of unintended side-effects such as changed of signedness. Particularly when using bit-wise operators. By splitting an expression up, you might get a different result depending on the variable types involved. – Lundin Sep 25 '18 at 06:55
  • @Lundin Thanks for the link, interesting read. Though my comment was specifically about the term "C/C++". I have to disagree with the edit. It's not clear whether Raj is asking about C++ or both languages, and the question would be fine if it asked about both. At the very least, since the title asked specifically for C++, we can assume it wasn't strictly about C. So I've edited the question to reflect that. In any case, it makes the question more useful to future readers, able to reach a wider audience. – François Andrieux Sep 25 '18 at 11:46
  • @Lundin I seem to have missed a piece of the discussion. I don't fully agree with it but I've removed the c++ tag I added so as to not step on any toes. – François Andrieux Sep 25 '18 at 11:49
  • @FrançoisAndrieux As per the linked policies (which are not yet live), we should either close the question as unclear or re-tag to C, since nothing in the question is unique to C++. The main point being that reducing friction between new and veteran users is more important than correcting the OP's misunderstandings about "C/C++". The comment field is not a good place to educate them about that. If you disagree or have ideas of your own, please add them to meta. The discussion is open and the more that contribute, the better. I'll try to refine the community consensus out of it. – Lundin Sep 25 '18 at 11:53

2 Answers2

5

Yes, bitwise AND is transitive as you've used the term.

It's perhaps easier to think of things as a stack of bits. So if we have four 4-bit numbers, we can do something like this:

A = 0xB;
B = 0x3;
C = 0x1;
D = 0xf;

If we simply stack them up:

A    1 0 1 1
B    0 0 1 1
C    0 0 0 1
D    1 1 1 1

Then the result of a bitwise AND looks at one column at a time, and produces a 1 for that column if and only if there's a 1 for every line in that column, so in the case above, we get: 0 0 0 1, because the last column is the only one that's all ones.

If we split that in half to get:

A    1 0 1 1
B    0 0 1 1
A&B  0 0 1 1

And:

C    0 0 0 1
D    1 1 1 1
C&D  0 0 0 1

Then and those intermediate results:

A&B 0 0 1 1 
C&D 0 0 0 1
End 0 0 0 1

Our result is still going to be the same--anywhere there's a zero in a column, that'll produce a zero in the intermediate result, which will produce a zero in the final result.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
4

The term you're looking for is associative. We generally wouldn't call a binary operator "transitive". And yes, & and | are both associative, by default. Obviously, you could overload the operators to be something nonsensical, but the default implementations will be associative. To see this, consider one-bit values a, b, and c and note that

(a & b) & c == a & (b & c)

because both will be 1 if and only if all three inputs are 1. And this is the operation that is being applied pointwise to each bit in your integer values. The same is true of |, simply replacing 1 with 0.

There are also some issues to consider if your integers are signed, as the behavior is dependent on the underlying bit representation.

Silvio Mayolo
  • 62,821
  • 6
  • 74
  • 116
  • 1
    Of course, you *could* consider `&` to define a relation if you convert the result to a boolean, e.g. `if (x & 4) ...` . Then that relation certainly wouldn't be transitive, e.g. `1 & 3` converts to true and `3 & 2` converts to true but `1 & 2` converts to false. (This is isomorphic to the classic non-transitive relation e.g. "A and B have a shared interest".) – Daniel Schepler Sep 25 '18 at 01:32