Remember our round function?

It worked fine for postive nos. but not for negative. The reason is we need to add .5 to a positive no. but subtract .5 from a negative in order to round it.

We can do this by using an if statement

What this says roughly is

if the expression in parentheses is true

then execute the next statement

otherwise

execute this alternate statement

The expression in parentheses is known as a logical expression (or boolean expression). We need to study logical expressions before we can really study if statements.

Logical Expressions

A logical expression is one which lets us test a relationship between two operands and express the result as a boolean— that is, true or false. An example is

n < 3

which evaluates to true if n is less than 3 and false if n is either equal to or greater than 3. The symbol < in this context is known as a relational operator.

There are six relational operators, all of which take two operands.

operator
operation
<
left operand is less than? right operand
>
left operand is greater than? right operand
<=
left operand is less thanor equal to? right operand
>=
left operand is greater thanor equal to? right operand
==
left operand is equal to? right operand
!=
left operand is not equal to? right operand

Again, the outcome of a relational operation is always boolean—true or false.

Boolean Operators

By themselves, the relational operators don't allow us to write terribly interesting functions yet. However, we can combine relationships, using three special boolean operators. Boolean operators are like relational operators in that they produce true or false results. The difference is that their operands also have to be boolean.

Operator Kind Relationship
&& binary And
|| binary Or
! unary Not

They correspond to what you would expect and, or and not to mean in ordinary speech. But we can define them more rigorously using a table.

a b a && b a || b !a
false false false false true
false true false true true
true false false true false
true true true true false

a||b is true if either a or b is true

a&&b is true only if both a and b are true

Now this lets us construct more interesting expressions such as

test whether n is 3 or between 7 and 10

The equivalent logical expression is

n == 3 || n>= 7 && n<= 10

Of course, if I didn't mean to include the end points when I said 'between' (open interval instead of a closed interval,

n == 3 || n> 7 && n< 10

Notice, for this to work, relational operators have to have a higher precedence than the boolean operators && and ||, as indeed they do.

Table of Precedence

Here is a table for the precedence of all the operators we know about so far

Operator Precedence Description
!   +   - Highest logical not, unary plus, unary minus
*   /   %   multiplication, division, modulo
+   - addition, subtraction
<   <=   >   >= relational inequalities
==   != equal, not equal
&& and
|| or
= Lowest assignment

Because and (&&) and or(||) have a lower precedence than the relational operators, the relational operations are carried out first. That is, it as if we put in parentheses as follows:

return (number == 4) || (number >= 7) && (number <= 10)

This makes sense because the relational operators can have non-boolean operands, but they will produce boolean results. || and &&, however, require boolean operands (as well as producing boolean results).

So you do the relational operations first, getting all boolean results, then you use the boolean operators to combine those results.

Logicists (or philosophers) would consider the three phrases to be propositions each of which is either true of false

Bool Conversions

Conversion to Bool

Integer types are converted to bool as follows:

  1. 0 is converted to false
  2. anything else is converted to true

Integer types include both int and char. Note also that since doubles can be converted to ints, this effectively means doubles can be converted to bool as well.

If an int value occurs where a bool is expected, this conversion is often applied automatically, e.g

if (i) x*=i;
else x+=1;

This is generally regarded as poor style.

Note: We haven't actually studied if yet (next topic!) but the meaning should be clear.

Conversion from Bool

values of type bool can be converted to int as follows:

  1. false is converted to 0
  2. true is converted to 1

Again, if a bool value is encountered where an int is expected the conversion can occur automatically. In the following example flag is a bool and x is a double:

x = x + flag;

Since x is a double and only a double can be added to a double, the value of flag is first converted to an int ( 0 or 1) and then that int is converted to a double (0.0 or 1.0).

If flag is false, x remains unchanged. If true, 1.0 is added to x.

Such "clever" programming is seldom justified and we will penalize it as bad style.

The Short Circuit Property

C++ (and many languages which borrow its syntax such as Java, JavaScript, PHP) have something know as the short-circuit property.

Within the bounds of precedence, boolean expressions are executed left to right. Once the outcome of the expression is known, execution stops with no farther evaluation.

In the above example, the steps are as follows.

  1. evaluate whether the first proposition is true or false (number==4)
  2. evaluate the second proposition (number >=7)
  3. evaluate the third proposition (number <= 10)
  4. combine the second and third results by anding them
  5. combine first result by oring it with result of step 4.

if we input to number a value of 4, the first proposition will be true. Since that guarantees the entire combined proposition is true (true or anything else is always true), step 1 is the only step that is executed.

If we input 5 or 6, the first proposition will be false, proposition two will be false, guaranteeing the entire proposition is false, so execution stops after step 3.

Let's run this example again, focusing on the short-circuit property.


Code Notes

1. Try editing the code to add a cin statement just before the return in main. Then use it to enter your own data. See if you can get the expression to quit evaluating on any of the terms.


Exercises

Given four integer variables, A, B, C and D, create functions to do the following:

  1. return true if any of them is negative.
  2. return true if A is the smallest value.
  3. return true if any pair is equal.
  4. return true if the product of any pair is equal to the product of the other pair.

Solutions

bool anyNegative(int A, int B, int C, int D){
    return A < 0 || B < 0 || C < 0 || D < 0;
}
bool isALeast(int A, int B, int C, int D){
    return A < B && A < C && A < D;
}
bool anyEquality(int A, int B, int C, int D){
    return A == B || A == C || A == D || B == C || B == D || C == D;
}
bool productEquality(int A, int B, int C, int D){
    return AB == CD || AC == BD || AD == BC;
}

Examples Shown in Full