chipKIT® Development Platform

Inspired by Arduino™

Bitwise Binary OR AND XOR Clarification

Created Thu, 11 Feb 2016 21:17:49 +0000 by FredCailloux


FredCailloux

Thu, 11 Feb 2016 21:17:49 +0000

Just a quick question in relation to logical operators. C++ makes a distinction between Bitwise Binary and logical operators. | is Bitwise OR & is Bitwise AND ~ is Bitwise NOT || is Binary OR && is Binary AND ! is Binary NOT What about ^ Bitwise XOR Exclusive OR ? According to the Arduino reference it is a Bitwise operator Most documentation concerning XOR ^ do not make the distinction between Bitwise or Binary. What is the situation exactly ? Is ^ Bitwise and Binary ? Is there another character sign or letter for XOR Binary ?


majenko

Thu, 11 Feb 2016 22:07:08 +0000

It is bitwise, but like all bitwise operators the result of the bitwise can be used as true/false.

Binary, like && and || can only operate on discrete true or false values. The fuzziness comes when you ask "what is true" and "what is false"?

In C a 0 is false, and any other value is true. So the value 3 is true. So with binary you have "3 && 8" would be true since both 3 and 8 are true. With bitwise "3 & 8" would be 0 since that is the bitwise result of AND-ing 3 and 8 (0b0011 & 0b1000 = 0b0000). So that would be false, not true. Hence the distinction between binary and bitwise.

With XOR it returns, of course, the XOR of the two values, as you would expect. But there is no equivalent XOR binary operator. Or is there...?

The truth table for XOR:

A|B|Q
=====
0|0|0
0|1|1
1|0|1
1|1|0

So it is false when A and B are the same, or true when A and B differ. So, you could say that:

Q is true if A is not equal to B.

Or...

if (A != B) { ... }

And that is why there is no actual XOR operator for binary in C like the bitwise operator. It is redundant, since "not-equal" performs the exact same job. Of course, that relies on A and B being actual single-bit binary values, otherwise it will compare the numbers in there. So you need to be a little cleverer:

if (((A > 0) && (b == 0)) || ((A == 0) && B > 0))) { ... }

Or, to make it smaller, you could use the ! operator to force an inverted binary value:

if ((!A) != (!B)) { ... }

Or, since we now have something that is either 0 or 1, since !3 is 0 and !0 is 1, you can:

if ((!A) ^ (!B)) { ... }

Cunning, huh? By reducing the values to 0 or 1 suddenly the bitwise and binary operators converge. They become identical.


FredCailloux

Thu, 11 Feb 2016 22:23:47 +0000

Then I could use something like this

#define ¨ != 
... some code
wr = (bit1 ¨ bit2 ) ;
... some more code

Can I? ( But I wont because then my code would become just a little more confusing 8-)


majenko

Thu, 11 Feb 2016 23:14:05 +0000

No, you can't do that - ¨ is not a valid macro name.

You could do:

#define XOR(A, B) ((!A) != (!B))

if (XOR(val1, val2)) { ... }

That would cope with A and B being integers or whatever rather than just boolean.