Boolean Logic


The bool type introduced in the last chapter can hold one of only two values, true or false. This type is often used to record the result of some operation, so that you can act on this result. In particular, bool types are used to store the result of a comparison.

Note

As an historical aside, it is worth remembering (and respecting) the English mathematician George Boole, whose work in the mid-nineteenth-century forms the basis of Boolean logic.

As an example, consider the situation (as mentioned in the introduction to this chapter) that you want to execute code based on whether a variable, myVal, is less than 10. To do this, you need some indication of whether the statement "myVal is less than 10" is true or false, that is, you need to know the Boolean result of a comparison.

Boolean comparisons require the use of Boolean comparison operators (also known as relational operators), which are shown in the following table. In all cases here var1 is a bool type variable, while the types of var2 and var3 may vary.

Operator

Category

Example Expression

Result

==

Binary

var1 = var2 == var3;

var1 is assigned the value true if var2 is equal to var3, or false otherwise.

!=

Binary

var1 = var2 != var3;

var1 is assigned the value true if var2 is not equal to var3, or false otherwise.

<

Binary

var1 = var2 < var3;

var1 is assigned the value true if var2 is less than var3, or false otherwise.

>

Binary

var1 = var2 > var3;

var1 is assigned the value true if var2 is greater than var3, or false otherwise.

<=

Binary

var1 = var2 <= var3;

var1 is assigned the value true if var2 is less than or equal to var3, or false otherwise.

>=

Binary

var1 = var2 >= var3;

var1 is assigned the value true if var2 is greater than or equal to var3, or false otherwise.

You might use operators such as these on numeric values in code such as:

 bool isLessThan10; isLessThan10 = myVal < 10; 

This code will result in isLessThan10 being assigned the value true if myVal stores a value less than 10, or false otherwise.

You can also use these comparison operators on other types, such as strings:

 bool isKarli; isKarli = myString == "Karli"; 

Here, isKarli will only be true if myString stores the string "Karli".

You can also focus on Boolean values:

 bool isTrue; isTrue = myBool == true; 

although here you are limited to the use of == and != operators.

Note

Note that a common code error occurs if you unintentionally assume that because val1 < val2 is false, then val1 > val2 is true. If val1 == val2 then both these statements will be false. I'm mentioning this here because it's a mistake I've made in the past!

There are some other Boolean operators that are intended specifically for working with Boolean values, shown in the following table.

Operator

Category

Example Expression

Result

!

Unary

var1 = ! var2;

var1 is assigned the value true if var2 is false, or false if var2 is true. (Logical NOT.)

&

Binary

var1 = var2 & var3;

var1 is assigned the value true if var2 and var3 are both true, or false otherwise. (Logical AND.)

|

Binary

var1 = var2 | var3;

var1 is assigned the value true if either var2 or var3 (or both) are true, or false otherwise. (Logical OR.)

^

Binary

var1 = var2 ^ var3;

var1 is assigned the value true if either var2 or var3, but not both, are true, or false otherwise. (Logical XOR, or exclusive OR.)

So, the last code snippet above could also be expressed as:

 bool isTrue; isTrue = myBool & true; 

The & and | operators also have two similar operators, known as conditional Boolean operators, shown in the next table.

Operator

Category

Example Expression

Result

&&

Binary

var1 = var2 && var3;

var1 is assigned the value true if var2 and var3 are both true, or false otherwise. (Logical AND.)

||

Binary

var1 = var2 || var3;

var1 is assigned the value true if either var2 or var3 (or both) are true, or false otherwise. (Logical OR.)

The result of these operators is exactly the same as & and |, but there is an important difference in the way this result is obtained, which can result in better performance. Both of these look at the value of their first operand (var2 in the preceding table) and based on the value of this operand may not need to process the second operator (var3 above) at all.

If the value of the first operand of the && operator is false, then there is no need to consider the value of the second operand, because the result will be false regardless. Similarly, the || operator will return true if its first operand is true, regardless of the value of the second operand.

This isn't the case for the & and | operators you saw earlier. With these, both operands will always be evaluated.

Because of this conditional evaluation of operands, you will see a small performance increase if you use && and || instead of & and |. This will be particularly apparent in applications that use these operators a lot. As a rule of thumb, always use && and || where possible.

Note that these operators really come into their own in more complicated situations, where computation of the second operand is only possible with certain values of the first operand, for example:

 var1 = (var2 != 0) && (var3 / var2 > 2); 

Here, if var2 is zero then dividing var3 by var2 will result in either a "division by zero" error or var1 being defined as infinite (the latter is possible, and detectable, with some types such as float).

Bitwise Operators

In the light of the discussion in the last section, you may be asking why the & and | operators exist at all. The reason is that these operators may be used to perform operations on numeric values. In fact, they operate on the series of bits stored in a variable rather than the value of the variable.

Let's consider these in turn, starting with &. Each bit in the first operand is compared with the bit in the same position in the second operand, resulting in the bit in the same position in the resultant value being assigned a value as shown in the following table.

Operand 1 Bit

Operand 2 Bit

& Result Bit

1

1

1

1

0

0

0

1

0

0

0

0

| is similar, but the result bits are different, as shown in the next table.

Operand 1 Bit

Operand 2 Bit

| Result Bit

1

1

1

1

0

1

0

1

1

0

0

0

For example, consider the operation shown in the following code:

 int result, op1, op2; op1 = 4; op2 = 5; result = op1 & op2; 

Here, you must consider the binary representations of op1 and op2, which are 100 and 101, respectively. The result is obtained by comparing the binary digits in equivalent positions in these two representations as follows:

  • The leftmost bit of result is 1 if the leftmost bit of op1 and op2 are both 1, or 0 otherwise.

  • The next bit of result is 1 if the next bit of op1 and op2 are both 1, or 0 otherwise.

  • Continue for all remaining bits.

In this example, the leftmost bits of op1 and op2 are both 1, so the leftmost bit of result will be 1, too. The next bits are both 0, and the third bits are 1 and 0, respectively, so the second and third bits of result will be 0. The final value of result in binary representation is, therefore, 100, so result is assigned the value 4. This is shown graphically in the following table.

1

0

0

4

&

1

0

1

&

5

1

0

0

4

The same process occurs if you use the | operator, except that in this case each result bit is 1 if either of the operand bits in the same position is 1. This is shown in the next table.

1

0

0

4

|

1

0

1

|

5

1

0

1

5

You can also use the Δ^ operator in the same way, where each result bit is 1 if one or other of the operand bits in the same position is one, but not both, as shown in the following table.

Operand 1 Bit

Operand 2 Bit

^ Result Bit

1

1

0

1

0

1

0

1

1

0

0

0

C# also allows the use of a unary bitwise operator (~), which acts on its operand by inverting each of its bits, such that the result is a variable having values of 1 for each bit in the operand that is 0, and vice versa: This is shown in the following table.

Operand Bit

~ Result Bit

1

0

0

1




Beginning Visual C# 2005
Beginning Visual C#supAND#174;/sup 2005
ISBN: B000N7ETVG
EAN: N/A
Year: 2005
Pages: 278

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net