To be AND/OR/XOR/NOT to be, that is the answer.
(An Introduction to Boolean Operators)
By: David Ray

I’ve been asked a lot about the Boolean operators lately, there seems to be some confusion in how they work.  This article is going to discuss Boolean operators in a fair level of detail.  My main focus will be using them in C and C++, but the basics apply to all programming languages.  I have never seen or used a language that didn’t have these operators, although there names have varied.

I am going to start of by explaining all of the operators in non-math terms.  Then we’ll move on to logical operators, and then to bitwise operators.

Everybody knows how AND works.  For example, you eat lunch when it’s lunch time AND you are hungry.  Some people ignore the first condition, but work with me on this.  If it’s lunch time but your not hungry, there’s really no point in eating.  If your hungry, but it’s not lunch time yet, you may have to put it off until it is.  So you really can’t eat lunch until both conditions are met.  That’s what AND is all about.

Everybody also knows how OR works.  When you’re deciding on a snack from the snack machine, you can have a candy bar OR you can have chips.  You can also have both, but that doesn’t really matter as long as either of the conditions exist.

The NOT condition is a little bit more convoluted, but not by much.  For example, you can driver your car as long as your NOT out of gas.  It means that the condition must NOT be true for the statement to be true.

The XOR, also called eXclusive OR, is the most confusing to most people.  But think of it this way, when you go to a movie theater, you can watch what’s in theater one, OR what’s in theater two, but you can’t watch both simultaneously.  That’s an XOR condition, because you can see movie one XOR movie two.  You can’t have both true at the same time, but either one can be true.

Okay, now that we understand the four operators that we’re discussing we can proceed.  We also need to explain the idea behind logical operators though.  Which is really quite simple.  A logical operator always returns TRUE or FALSE, never ever maybe.  You can use as many operators as you want, as long as the end result is always just TRUE or FALSE it’s a logical operator.  As far as a computer is concerned, FALSE is the same as a zero, and TRUE is the same as any value NOT zero, usually a it’s one, but not always.

So given that a computer uses ones and zeros for representing truth, you can generate what’s known as a truth table, like so:
 

AND Truth Table
A
0
0
1
1
B
0
1
0
1
Result
0
0
0
1




As you can see, all of the results are false, unless both A AND B are true.  The truth table for OR is like so:

OR Truth Table

A
0
0
1
1
B
0
1
0
1
Result
0
1
1
1




In this table the result is true if either or both of A OR B are true.  The truth table for XOR is:

XOR Truth Table

A
0
0
1
1
B
0
1
0
1
Result
0
1
1
0




In this table the result is true if either A OR B is true, but not if A AND B is true.  We don’t need a table for NOT, because it simple reverses TRUE and FALSE.

Now we’re going to switch our focus to C/C++ programming.  These logical operators are all represented using symbols.  The AND operator is "&&", the OR operator is "||", the XOR operator is "^^", and the NOT operator is "!".  Using this knowledge we can test conditions, let’s say we want to know if a value is between 1 and 9.  We can write the following code:

Condition #1
if(Value > 0 && Value <10)
 // Do something

The above statement checks to see if the value is greater than 0, AND the value is less 10.  If both of those conditions are true then it will do something.  The reason we did greater than zero rather than greater than one is that we wanted one included in our value.  And the value of one is NOT greater than one, it’s equal to one.  We can also test to see if the value isn’t between 1 and 9 by doing this:

Condition #2
if(Value <1 || Value > 9)
 // Do something

This tests to see if the value is less than one OR greater than nine.  We can use this logic with the NOT operator to turn it into the same as our first statement, like so:

Condition #3
if(!(Value < 1 || Value>9))
 // Do something

This is saying if the value is NOT less than one OR greater than nine, then perform an action.  A slightly more confusing way of making our second condition doing this would be by using XOR:

Condition #4
if(Value > 0 ^^ Value < 10)
 // Do something

What we’re saying here is if the value is greater than zero, OR if the value is less than 10, but not if both of those are true, then do something.  So in effect, this makes it so that all values that aren’t between 1 and 9 are true.  And that’s pretty much how the logical operators work.

Now we’re going to move onto what’s known as bitwise operators.  I’m going to be using binary and hexadecimal extensively in this section, if you aren’t familiar with these you should read my other article on that subject.

All bitwise operators work exactly the same as the logical operators, except for the fact that they perform there operation on every bit in the values.  Rather than just operating on a single true and false value, it will operate on each bit treating the values as several true or false statement in a single value.  The symbols used for the bitwise operators are: & is AND, | is OR, ^ is XOR, and ~ is NOT.  The best way to explain how these operators work is by example.

For the following examples, the first value will be 5 or 101b in binary, and the second value will be 6 or 110b in binary.

If we do 5 & 6 our result will be 4.  Here’s why:

The value of 5 is 101b, we then AND it bit by bit with the value of 6 which is 110b.  So we take the rightmost bit, or bit zero, and we AND them together to get 1&0=0.  We then do that for the next bit and we get 0&1=0.  And finally the third and last bit we have 1&1=1.  If we put those all back together we get 100b or 4 in decimal.  Writing these equations in a stack form often helps, so here it is again:
 


&
=
5
6
4
=
=
=
101b
110b
100b



As you can see, the only column that is true is the one where both values are one.  Now let’s do the same exact equation using OR instead of AND.
 

|
=
5
6
7
=
=
=
101b
110b
111b



Here we have the situation where if either digit is a one then the result is one.  Since there is at least a single one in every column, the result is a one in every column.  Now using all the same rules, let’s do the same with XOR:
 

^
=
5
6
3
=
=
=
101b
110b
011b



With XOR the result it true if either value is true, but not both values.  As we can see in the first and second columns there is only a single one, and therefore the result is one for each column.  In the third column however, both values are a one, and therefore the result is zero.  The NOT operator is the simplest, but often most misunderstood of them all since you only need one value.  Here’s an example:

~ 5 = 2 in binary it is ~101b = 010b

As you can see, the NOT operator simply reversed the state of every bit.  If the bit started as a one, it ended as a zero, and if it started as a zero it ended as a one.

This may all seem kind of abstract and difficult to understand why you would ever use this.  So let’s make a practical example.  We’re going to assign colors to each bit in our example.  The first bit is going to represent the color Blue, the second bit will be Green, and the third bit will be Red.  So we have a color table like so:

001b = Blue
010b = Green
100b = Red

Now let’s say we want to make the color purple, we want to combine Red and Blue to make purple, so we do this:

Blue | Red = Purple
001b | 100b = 101b

Let’s say we now want to take that purple color and invert it like a negative photograph, we can simply NOT the value of Purple:

~ Purple = Green
~ 101b = 010b

Or as another example, let’s say we have the color White, which happens to be a combination of Red Green and Blue, which would have the binary value of 111b.  But let’s say we want to remove all of the Green from the color.  So we want to AND it with NOT Green, or:

White & (~ Green) = Purple
111b & (~ 010b = 01b) = 101b

You can use XOR to make creative effects, although this is a poor example of using XOR, we should do it just for consistency sake:

Yellow ^ Purple = Aqua
110b ^ 101b = 011b

But the use of bitwise operators isn’t limited to just artwork.  It has many other uses, you just have to be clever in how you use it.  For example, let’s say you wanted to figure out if a value is odd or even.  You could divide by two and then figure out if it has a fractional component, or you could AND the number with one, and if it is odd the return value will be one, if it’s even it would be zero.  This is always true for any integer value.

There are also two more bitwise operators that aren’t based on the logical operators.  They are right and left shift.  The right shift operator is ">>", and the left shift operator is "<<".  These two functions quite simply shift all of the bits in the value right or left by the number of positions you designate.  So for example, if you had the number 16 or 10000b, and you right shifted by 2 places you would have:

16 >> 2 = 4
10000b >> 2 = 00100b

If you shifted left instead, you would get:

16 << 2 = 64
10000b << 2 = 1000000b

These operators are useful because you can use them in place of multiply and divide, but only if your multiplying or dividing by a power of 2.  Right shifting by 1 is the same as dividing by 2, and left shifting is the same as multiplying by 2.  Shifting bits is extremely fast.  And going back to the color examples, you can get some "interesting" effects that way.
 


Home

Last revised:  March 24, 1998