A **numerical relation** is a statement that compares two numerical
expressions. The relation is either true or false (when the comparison is
made), and the Sorcerer can always tell which, just by evaluating the
expressions and comparing the resulting numbers.

Examples:

1=1 This is true

1=0 This is false

X=6 This is true if X has the value of 6 at the time

the comparison is made. Otherwise it is false.

A+B=C This is true is the value of A plus the value of B

equals the value of C at the time of the evaluation.

Otherwise it is false.

*The equal sign as used in these examples is not the
assignment operator (the one that goes with a LET statement).*

Numerical relations have this form:

<first expression> <relation operator> <second expression>

The relation operators are:

operator examples

= equal 1=1 is true, 1=0 is false

<> or >< not equal 2<>3 is true, 2<>2 is false

< less than 2<4 is true, 0<-2 is false

> greater than 1>-1 is true, 2>3 is false

<= or =< less than or equal 1<=1 and 6<=7 are true, 1<=0 is false

>= or => greater than or equal -1>=-1 and -1>=-2 are true, 0>=1 is false

A numerical expression is a mathematical entity that always has a number
value. Similarly, a logical expression is an entity that always has a
logical value (sometimes called a **truth value**). Numerical
expressions can have any number for their values, but logical expressions
can take on only two different logical values: true and false. (The
Sorcerer gives expresslon that are true the value of -1, and those that
are false it gives the value of 0. The Sorcerer always knows when to treat
0 and -1 as numbers and when to treat them as truth values.)

Numerical relations are simple examples of logical expressions. **Logical
operators** let you build more complicated expressions out of simple
ones. There are three of these operators:

NOT <expression>

<first expression> AND <second expression>

<first expression> OR <second expression>

The NOT expression is true when the expression is false, and vice versa.

Example:

NOT X = 1 is true if X doesnothave value l,

and is false if Xdoeshave value 1.

This is the same as the relation X <> 1.

The AND expression is true in the case of **both** of the simpler
expressions being true. If either or both of them are false, then the AND
expression is false.

Examples:

X = 1 AND A = B is true just in the case that X has value 1and

A has the same value as B, otherwise it is false.

The OR expression is true if either of the expressions is true or if
they are both true. It is false only if **both** of the expressions
are false.

Examples:

X < 1 OR X = 1 is true if X is less than 1 or if X is equal to 1.

It is false if X is greater than 1. This is just

the same as the relation X <= 1.

X = 1 OR Y = 2 is true if X has the value 1, or if Y has the value 2,

or both conditions hold. Otherwise it is false.

The OR operator is sometimes called the **inclusive OR**, because it
includes as true the case where both simpler expressions are true.

There is another logical operator called the **exclusive OR **(XOR),
which Standard BASIC does not recognize. An exclusive OR expression is
true if either of the simpler expressions are true, but not if both are.

Most people use the English word "or" as an exclusive OR
operator. Don't let this confuse you; an OR expression in Standard BASIC
**is** true if both of its parts are true (and, of course, if either
is true). Think of the Standard BASIC OR as the legalistic term "and/or."

Before the Sorcerer can decide whether a logical expression is true or
false, it must decide whether the numerical relations in the expression
are true or false. And before it can make **that** decision, it must
compute the values of the individual numerical expressions in the
relation.

In Chapter 5 you learned the order of precedence for numerical operations. The numerical relations and logical operators are part of this order of precedence. This is the complete sequence:

- ( ) Expressions inside parentheses.
- ^ Exponentiation.
- - Negation.
- * and / Multiplication and division.
- + and - Addition and subtraction.
- Numerical relations (all have the same precedence)
- = Equal
- <> Not equal
- < Less than
- > Greater than
- <= Less than or equal
- >= Greater than or equal

- NOT
- AND
- OR

Logical decisions may be made dependent on the values of **counters,
accumulators** and **flags**.

You may repeat a program (or a part of a program) an indefinite number
of times with GOTO statements. You can keep track of the number of
repetitions with a **counter**. You can instruct the Sorcerer to make
a decision when the counter reaches a certain value.

You may wish to keep running totals of certain values; this you do with
**accumulators**.

You may want something to happen at a certain point in a program. You
tell the Sorcerer that when a particular variable called a **flag**,
has a certain value, it is time for that something to happen. You usually
set a value that the variable would not normally reach. (For example, the
program may instruct the operator to enter a number of ages, and to enter
0 when he wishes to end the program, that being an age that would not
normally be input.) Each time through a loop, the program examines the
variable to see if it is equal to (or greater than, or less than) the
variable.

In Chapter 4 you saw how the Sorcerer makes decisions with IF...THEN
statements. Here are some more examples, using numerical relations and
logical expressions with variables, among them **counters, accumulators**
and **flags**.

100 IF X=Y THEN 100

70 IF (A=B OR C<>D+2) THEN PRINT "HELP!"

200 IF (OSCAR(X)=SAM(2)) THEN STOP

10 IF NOT (A*2=6 OR X<Y) AND A(Q)=X^2 THEN 300

Here is a program that asks you to choose three numbers and then tells
you something about those numbers. This program has a **counter** (the
variable named CR) to keep track of how many times the operation is
performed. The counter, together with a relational operator, also ensures
that the message about how to terminate the program is only printed once,
at the first run-through of the program.

10 LET CR=0

20 PRINT:PRINT "PICK THREE NUMBERS";

30 IF CR>0 THEN 60

40 PRINT

50 PRINT "(YOU MAY END THIS PROGRAM BY ENTERING THREE ZEROS.)"

60 LET CR=CR+1

70 INPUT A,B,C

80 IF A=B OR B=C OR A=C THEN 110

90 PRINT "YOUR NUMBERS ARE ALL DIFFERENT."

100 GOTO 20

110 IF A=B AND B=C THEN 140

120 PRINT "TWO OF YOUR NUMBERS ARE THE SAME."

130 GOTO 20

140 IF A<>0 THEN 180

150 PRINT "YOU TRIED";CR-1;"SETS OF NUMBERS ";

160 PRINT "(EXCLUDING '0,0,0')."

170 STOP

180 PRINT "ALL OF YOUR NUMBERS ARE THE SAME."

190 GOTO 20

Notice that in 150 1 is subtracted from the CR total to avoid counting
the entry of three zeros as a try. These three zeros are **flags**.

The city council wishes to know the average ages of children in various municipally funded projects. They have a program that runs on their new Sorcerer. This program instructs the operator to enter the sex and age of each child in turn. If he accidentally enters the wrong number (for instance, no one over the age of thirteen is enrolled in these projects), the program tells him to make the entry again.

10 C1=0:A1=0:A2=0:S1=0:S2=0:T=0:REM INITIALIZATION

20 PRINT

30 PRINT "ENTER CHILD'S SEX FIRST, ACCORDING TO THIS CODE:"

40 PRINT "1=BOY, 2=GIRL. THEN ENTER CHILD'S AGE."

50 PRINT "EXAMPLE, FOR BILLY SMITH, AGE 10, ENTER: 1,10"

60 PRINT "(TO FIND THE AVERAGES, ENTER 0,0)"

70 PRINT

80 C1=C1+1

90 PRINT "CHILD #";C1;

100 INPUT SX,AJ

110 IF SX=0 AND AJ=0 THEN 230

120 IF SX=1 OR SX=2 THEN IF AJ>0 AND AJ<14 THEN 150

130 PRINT "BAD INPUT. PLEASE TRY AGAIN."

140 GOTO 90

150 IF SX=2 THEN 190

160 LET S1=S1+1

170 LET A1=A1+AJ

180 GOTO 210

190 LET S2=S2+1

200 LET A2=A2+AJ

210 LET T=T+AJ

220 GOTO 80

230 PRINT

240 IF S1>0 THEN PRINT "THE AVERAGE AGE OF THE BOYS IS";A1/S1

250 IF S2>0 THEN PRINT "THE AVERAGE AGE OF THE GIRLS IS";A2/S2

260 IF S1=0 AND S2=0 THEN PRINT "NO ENTRIES":STOP

270 PRINT "THE AVERAGE AGE OF ALL THE CHILDREN IS";T/(S1+S2)

RUN

ENTER CHILD'S SEX FIRST, ACCORDING

TO THIS CODE: 1=BOY, 2=GIRL. THEN

ENTER CHILD'S AGE. FOR EXAMPLE, FOR

BILLY SMITH, AGE 10, ENTER: 1,10

(TO FIND THE AVERAGES, ENTER 0,0.)

CHILD #1? 1,3

CHILD #2? 2,4

CHILD #3? 3,2

BAD INPUT. PLEASE TRY AGAIN.

CHILD #3? 2,0

BAD INPUT. PLEASE TRY AGAIN.

CHILD #3? 2,2

CHILD #4? 1,6

CHILD #5? 2,3

CHILD #6? 0,0

THE AVERAGE AGE OF THE BOYS IS 4.5

THE AVERAGE AGE OF THE GIRLS IS 3

THE AVERAGE AGE OF ALL THE

CHILDREN IS 3.6

Notice that in line 120 an IF...THEN statement is followed by another IF ... THEN. If both conditions are not fullfilled (i.e., if an improper entry is made), then the program does not continue to line 150. The "error message" prints instead, and the program requests a repeat of the input by returning to line 90 (By not going to line 80, the counter is not incremented until the program receives a proper input.)

Line 120 could be replaced by an equivalent statement:

120 IF (SX=1 OR SX=2) AND (AJ>0 AND AJ<14) THEN 150

These are the counters: C1 counts the number of inputs, S1 counts the boys and S2 counts the girls. The age accumulators are A1, for the boys, A2, for the girls and T, for all the children. SX=0 and AJ=0 are the flag conditions the program tests for.

Remember from Chapter 5 that, because the Sorcerer uses floating point numbers, it does not always store numbers the way you expect. You may tell the Sorcerer that when X=2 something must happen. That 2 may be the result of a computation that the Sorcerer has rounded off for screen display. The number may in actuality be 1.999994 which the Sorcerer does not think is the same as 2. Who knows what numbers lurk out there somewhere beyond the six digits that the Sorcerer prints on the screen?

To prove this point, try this program:

10 PRINT

20 INPUT "CHOOSE TWO NUMBERS";X,Y

30 PRINT "YOUR FIRST NUMBER IS";X

40 PRINT "YOUR SECOND NUMBER IS";Y

50 IF X=Y THEN PRINT "X=Y":GOTO 10

60 PRINT "X<>Y":GOTO 10

RUN

CHOOSE TWO NUMBERS? 1,1

YOUR FIRST NUMBER IS 1

YOUR SECOND NUMBER IS 1

X=Y

CHOOSE TWO NUMBERS? .9999994,1

YOUR FIRST NUMBER IS 1

YOUR SECOND NUMBER IS 1

X<>Y

You can avoid this problem by not using the "=" and "<>" operators. Replace them with the "<" and ">" operators.

A store owner came to the software department at Exidy to complain about
an account--balancing program that refused to work. One step in the
program required that a variable be equal zero. The statement was of the
order IF X=0 THEN do such-and-such. His program never did what it was
supposed to because X never **did** exactly equal 0; it was always a
few fractions of a cent larger or smaller. The software people got the "bug"
out of his program by substituting the statement:

IF X>-.001 AND X<.001 THEN

(This could be expressed more simply as

IF ABS(X)<.001 THEN ...

See Chapter 8.)

In other words, if X was within 1 /10 of a cent of the $100, then the decision was made. (This is the close-enough-for government-work principle.)

The <= operator is often used with integers. If you know the comparison will be made with an integer, remember that <=1 and <2 mean the same. If not, decide how accurate you must be, and then replace <=2 with, for instance, <2.001.

Another solution is to round or truncate numbers before making comparisons. The problem is not caused by BASIC but, rather, one intrinsic to computers.