Lecture 9: Branching II / Boolean Algebra |
George Boole (1815-1864)
English mathematician. His work "The mathematical analysis
of logic"
(1847) established the basis of modern mathematical logic, and his
boolean
algebra can be used in designing computers.
|
In the previous lecture (aula 8) we have seen
how we can control the flow of the program by the branching
instructions
if
... then and if ... then ... else. We used conditions
like
(x<1.0). Now imagine we apply this to calculate the square-root of (x2-
4).
Clearly, this doesn't have an answer for
x between -2
and +2. It would be nice to check if x is in this range or not.
We could solve this with
if (x<2) then
if (x>-2) then
WriteLn('Error');
Much nicer would be if we could do this in a single condition. We will
now see that exactly that is possible
if ((x<2) AND (x>-2)) then
WriteLn('Error');
which obviously mean that both conditions (x<2 and x>-2),
should be true for the complete condition to be true.
This is an example of a Boolean calculation
condition3 := condition1 AND
condition2;
if condition3 then instruction;
Other Boolean algebra operators that can be used in PASCAL are
OR
and XOR. (Others that are not implemented include NAND and
NOR).
The AND and OR operations are obvious. The XOR
operation is a little complicated. a XOR b means "a or b
true,
but not both!"
Finally, there is the boolean negator NOT. It means taking
the opposite; if a is TRUE, NOT a is FALSE,
and vice cerse. Wheras AND, OR and XOR
need
two operands (for example a XOR b), NOT needs only
one
(NOT a).
With these four operators we can calculate all possible conditions
we will need.
For completeness sake, here is the complete calculation tables
("truth
tables") for the four Boolean operators used in modern programming
languages.
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
a := 1;
b := -2;
c := 3;
d := 3;
if (a>0) then
WriteLn('TRUE')
else
WriteLn('FALSE');
(a>0)
TRUE
(b>0)
FALSE
(a>0) AND
(b>0)
FALSE
(a>0) OR
(b>0)
TRUE
(a>0) XOR
(b>0)
TRUE
NOT
(a>0)
FALSE
(NOT (a>0)) OR
(b>0)
FALSE
(2=b) OR (NOT
(2=b))
TRUE
(NOT (c>0)) XOR
(d>0)
TRUE
|
|
|
|
|
As an example, imagine we want to calculate 49 OR 24
First we have to convert these numbers to the binary system (see aula 3): 49 = 1*32 + 1*16 + 0*8 + 0*4 + 0*2 + 1*1 = 110001 24 = 0*32 + 1*16 + 1*8 + 0*4 + 0*2 + 0*1 = 011000 Then we do a bitwise calculation with the conventions as in the table above (1 OR 1 = 1, 1 OR 0 = 1, 0 OR 1 = 1, 0 OR 0 = 0), which will give 111001 This we then convert back to the decimal system and we get 111001 = 1*32 + 1*16 + 1*8 + 0*4 + 0*2 + 1*1 = 57 |
PROGRAM Years;
VAR ano: integer;
begin
WriteLn('From what year
are you?');
ReadLn(ano);
if (ano=1) then
writeln('primeiro
ano: MAT-1, CALC-1')
else
if (ano=2)
then
writeln('segundo ano: INF, LIN-ALG')
else
if (ano=3) then
writeln('terceiro ano: ELEC, FYS')
else
if (ano=4) then
writeln('quarto ano: QUI, MAT-2')
else
if (ano=5) then
writeln('quinto ano: PROJECTO')
else
writeln('>5: AINDA NAO ACABOU?');
end.
(Note the structure of the program, with indentations. Also note the
missing ; before every else).
This program will run without problem
From what year are you?
1
primeiro ano: MAT-1, CALC-1
From what year are you?
4
quarto ano: QUI, MAT-2
The structure is not very readable, though. To make it better, we
can
use case ... of. Whereas in "if
condition then instruction1" the condition is necessarily
of
the boolean type (TRUE or FALSE), in case
...
of we can use any type of variable that has discreet values
(in contrast to floating point variables which do not have discreet,
whole
number values).
Case expression
of
value1: instruction1; value2: instruction2; | valueN: instructionN; else instructionE; end; |
The expression needs to
result
in a value of any countable type (for example: integer, byte, boolean,
but also char. Not, for example: real or string). This can be a simple
variable or a calculation resulting in a value. The values value1
to valueN also have to be of the
same type;
As an example the above program rewritten to make use of case ...
of:
PROGRAM Years;
VAR ano: integer;
begin
WriteLn('From what year
are you?');
ReadLn(ano);
Case ano of
1:
writeln('primeiro
ano: MAT-1, CALC-1');
2:
writeln('segundo
ano: INF, LIN-ALG');
3:
writeln('terceiro
ano: ELEC, FYS');
4:
writeln('quarto
ano: QUI, MAT-2');
5:
writeln('quinto
ano: PROJECTO')
else
writeln('>5:
AINDA NAO ACABOU?');
end;
end.
This progam will have the same output as the program before, but now it is more readable.