LOGICAL Type and Variables

  ELECTIVE

  XECUTION S E ELECT THE TOPICS YOU WISH TO REVIEW S

:

  Selective Execution

  IF-THEN-ELSE-END IF Statement

  

  

  

   LOGICAL T YPE AND

  V ARIABLES LOGICAL values are either true or false. In Fortran, they must be written as .TRUE. and .FALSE. Note that the two periods surrounding TRUE and FALSE must be there; otherwise, they become identifiers. A variable that can hold one of the logical values is a logical variable and it is of type

LOGICAL. To declare a LOGICAL variable, do it as what you did for INTEGER and REAL

variables. But, use the type name LOGICAL instead. LOGICAL constants can have aliases declared with the PARAMETER attribute. LOGICAL variables can be initialized when they are declared and can be assigned a logical value.

  

However, a LOGICAL variable can only hold a logical value. Putting a value of any other type

( e.g. , INTEGER or REAL) into a LOGICAL variable will cause an error.

  The following are examples:

   Answer, Condition, Test, Value and Yes_and_No are LOGICAL variables that can hold either .TRUE. or .FALSE.: LOGICAL :: Answer, Condition, Test LOGICAL :: Value, Yes_and_No

   LOGICAL identifers Answer and Condition are aliases of .TRUE. and .FALSE.,

  respectively: LOGICAL, PARAMETER :: Answer = .TRUE., Condition = .FALSE.

   LOGICAL variables Test and PreTest are initialized to .TRUE. and .FALSE.,

  respectively: LOGICAL :: Test = .TRUE., PreTest = .FALSE.

   LOGICAL variables Cond_1, Cond_2 and Total are assigned with .TRUE., .TRUE. and .FALSE., respectively: LOGICAL :: Cond_1, Cond_2, Total Cond_1 = .TRUE. Cond_2 = .TRUE. Total = .FALSE.

  NPUT AND UTPUT LOGICAL I O

When using WRITE(*,*) to display a LOGICAL value, Fortran displays .TRUE. and .FALSE.

with T and F, respectively. When preparing input for READ(*,*), use T and F for .TRUE. and .FALSE., respectively.

  ELATIONAL PERATORS R O There are six relational operators:

  < : less than  <= : less than or equal to

   > : greater than  >= : greater than or equal to  == : equal to

   /= : not equal to 

  Here are important rules: Each of these six relational operators takes two operands. These two operands must

   both be arithmetic or both be strings. For arithmetic operands, if they are of diferent types (i.e., one INTEGER and the other REAL), the INTEGER operand will be converted to REAL.

  The outcome of a comparison is a LOGICAL value. For example, 5 /= 3 is .TRUE. and 7 + 3 >= 20 is .FALSE. All relational operators have equal priority and are lower than those of arithmetics operators as shown in the table below:

  Associati Type Operator vity

  • ** right to left

  Arithme

/ left to right *

tic

  • - left to right +

  Relation < < > > = /= none al = = =

  This means that a relational operator can be evaluated only if its two operands have

   been evaluated. For example, in a + b /= c*c + d*dexpressions a+b and c*c + d*d are evaluated before the relational operator /= is evaluated. If you are not comfortable in writing long relational expressions, use parenthesis. Thus, 3.0*SQRT(Total)/(Account + Sum) - Sum*Sum >= Total*GNP - b*bis equivalent to the following: (3.0*SQRT(Total)/(Account + Sum) - Sum*Sum) >= (Total*GNP - b*b) Although a < b < c is legal in mathematics, you cannot write comparisons this way in Fortran. The meaning of this expression is a < b and b < c. You should useto achieve this.

  XAMPLES E 3**2 + 4**2 == 5**2 is .TRUE. If the values of REAL variables a, b and c are 1.0, 2.0 and 4.0, respectively,

  

then b*b - 4.0*a*c >= 0.0 is equivalent to 2.0*2.0 - 4.0*1.0*4.0 >= 0.0,

which evaluates to -12.0 >= 0.0. Thus, the result is .FALSE. If REAL variables x and y have values 3.0 and 7.0, and INTEGER variables p and q have values 6 and 2, what is the result of x*x - y*y + 2.0*x*y /= p*q + p**3 - q**3? x*x - y*y + 2.0*x*y /= p*q + p**3 - q**3

  • --> 3.0*3.0 - 7.0*7.0 + 2.0*3.0*7.0 /= 6*2 + 6**3 - 2**3 --> [3.0*3.0] - 7.0*7.0 + 2.0*3.0*7.0 /= 6*2 + 6**3 - 2**3 --> 9.0 - 7.0*7.0 + 2.0*3.0*7.0 /= 6*2 + 6**3 - 2**3 --> 9.0 - [7.0*7.0] + 2.0*3.0*7.0 /= 6*2 + 6**3 - 2**3 --> 9.0 - 49.0 + 2.0*3.0*7.0 /= 6*2 + 6**3 - 2**3 --> [9.0 - 49.0] + 2.0*3.0*7.0 /= 6*2 + 6**3 - 2**3 --> -40.0 + 2.0*3.0*7.0 /= 6*2 + 6**3 - 2**3 --> -40.0 + [2.0*3.0]*7.0 /= 6*2 + 6**3 - 2**3 --> -40.0 + 6.0*7.0 /= 6*2 + 6**3 - 2**3 --> -40.0 + [6.0*7.0] /= 6*2 + 6**3 - 2**3 --> -40.0 + 42.0 /= 6*2 + 6**3 - 2**3 --> [-40.0 + 42.0] /= 6*2 + 6**3 - 2**3 --> 2.0 /= 6*2 + 6**3 - 2**3 --> 2.0 /= [6*2] + 6**3 - 2**3 --> 2.0 /= 12 + 6**3 - 2**3 --> 2.0 /= 12 + [6**3] - 2**3 --> 2.0 /= 12 + 216 - 2**3 --> 2.0 /= [12 + 216] - 2**3
  • --> 2.0 /= 228 - [2**3] --> 2.0 /= 228 - 8 --> 2.0 /= [228 - 8] --> 2.0 /= [220] --> 2.0 /= 220.0 --> .TRUE. In the above, please note the left-to-right evaluation order and the type conversion making 220 to 220.0 before carrying out /=

  OMPARING TRINGS C CHARACTER S

Characters are encoded. Diferent standards (e.g. BCD, EBCDIC and ASCII) may

have diferent encoding schemes. To write a program that can run on all diferent

kind of computers and get the same comparison results, one can only assume the

following ordering sequences: A < B < C < D < E < F < G < H < I < J < K < L < M < N < O < P < Q < R < S < T < U < V < W < X < Y < Z a < b < c < d < e < f < g < h < i < j < k < l < m < n < o < p < q < r < s < t < u < v < w < x < y < z 0 < 1 < 2 < 3 < 4 < 5 < 6 < 7 < 8 < 9

If you compare characters in different sequences such as 'A' < 'a' and '2' >= 'N',

you are asking for trouble since diferent encoding methods may produce

diferent answers. Moreover, do not assume there exists a specifc order among

upper and lower case letters, digits, and special symbols. Thus, '+' <= 'A', '*' >=

'%', 'u' > '$', and '8' >= '?' make no sense. However, you can always compare if

two characters are equal or not equal. Hence, '*' /= '9', 'a' == 'B' and '8' == 'b' are

perfectly fne.

  Here is the method for comparing two strings: The comparison always starts at the frst character and proceeds from left

   to right. If the two corresponding characters are equal , then proceed to the next

   pair of characters. Otherwise, the string containing the smaller character is considered to be

   the smaller one. And, the comparison halts. During the process comparison, if

   o both strings have consumed all of their characters, they are equal since all of their corresponding characters are equal. o otherwise, the shorter string is considered to be the smaller one.

  Compare "abcdef" and "abcefg" a b c d e f = = = < a b c e f g The frst three characters of both strings are equal. Since 'd' of the frst string is smaller than 'e' of the second, "abcdef" < "abcefg" holds.

  Compare "01357" and "013579" 0 1 3 5 7 = = = = = 0 1 3 5 7 9 Since all compared characters are equal and the frst string is shorter, "01357" < "013579" holds.

  What is the result of "DOG" < "FOX"? D O G < F O X The frst character (i.e., 'D' < 'F') determines the outcome. That is, "DOG" < "FOX" yields .TRUE.

  PECIAL OTE A S N

The priority of all six relational operators is lower than the string

//. Therefore, if a relational expression involves //, then all string

concatenations must be carried out before evaluating the comparison operator.

  Here is an example: "abcde" // "xyz" < "abc" // ("dex" // "ijk") --> ["abcde" // "xyz"] < "abc" // ("dex" // "ijk") --> "abcdexyz" < "abc" // ("dex" // "ijk") --> "abcdexyz" < "abc" // (["dex" // "ijk"]) --> "abcdexyz" < "abc" // ("dexijk") --> "abcdexyz" < "abc" // "dexijk" --> "abcdexyz" < ["abc" // "dexijk"] --> "abcdexyz" < "abcdexijk" --> .FALSE.

PERATORS AND

  XPRESSIONS LOGICAL O E

  

Fortran has five LOGICAL operators that can only be used with expressions whose results are

logical values (i.e., .TRUE. or .FALSE.). All LOGICAL operators have priorities lower than

rators. Therefore, if an expression involving arithmetic, relational

and logical operators, the arithmetic operators are evaluated first, followed by the relational operators, followed by the logical operators.

  These five logical operators are .NOT. : logical not.AND. : logical and.OR. : logical or

   .EQV. : logical equivalence.NEQV. : logical not equivalence  The following is a table of these operators, including there priority and associativity.

  Associati Type Operator vity

  • ** right to left

  Arithme

/ left to right *

tic

  • - + left to right Relation < < > > = /= none al = = = .NOT. right to left .AND. left to right Logical

  .OR. left to right .EQV. .NEQV. left to right RUTH ABLES T T

  The evaluation of logical expressions is determined by truth tables. Let us start with the .NOT. operator.

  

.NO Opera Resul

T. nd t

.TRUE. .FALS

  E. .FALSE .TRUE . .

  

Note that .NOT. is a unary operator. Therefore, .NOT. a yields .TRUE. (resp., .FALSE.) if the

value of LOGICAL variable a is .FALSE. (resp., .TRUE.).

  The following is the truth table of .AND.:

  .TRU .FALS .AND.

  E. E

.TRUE .TRU .FALS

.

  

E.

  E.

.FALS .FALS .FALS

E.

  

E.

  E.

  

Therefore, the result of logical expression a .AND. b is .TRUE. if and only if both operands a

and b are .TRUE.. In all other cases, the result is always .FALSE.

  The following is the truth table of .OR.:

  .TRU .FALS .OR.

  E. E

.TRUE .TRU .TRUE

.

  E. .

.FALS .TRU .FALS

E.

  

E.

  E.

  

Therefore, the result of logical expression a .OR. b is .FALSE. if and only if both operands a

and b are .FALSE.. In all other cases, the result is always .TRUE. In other words, if one of the

two operands of the .OR. operator is .TRUE., the result is .TRUE.

  The following is the truth table of .EQV.:

  .TRU .FALS .EQV.

  E. E

.TRUE .TRU .FALS

.

  

E.

  E.

.FALS .FALS .TRUE

E.

  E. .

  Therefore, the result of logical expression a .EQV. b is .TRUE. if and only if both operands a and b have the same value (i.e., both are .TRUE. or both are .FALSE.). As mentioned in xpressions, relational operators can only compare arithmetic values and cannot be used to compare logical values. To compare if two logical values are equal, use .EQV.

  The following is the truth table of .NEQV.:

  

.NEQ .TRU .FALS

V.

  E. E

.TRUE .FALS .TRUE

.

  E. .

.FALS .TRU .FALS

E.

  

E.

  E.

  

Therefore, the result of logical expression a .NEQV. b is .TRUE. if and only if both operands a

and b do not have the same value. As mentioned inxpressions, relational operators

can only compare arithmetic values and cannot be used to compare logical values. To compare if

two logical values are not equal, use .NEQV. Note that .NEQV is the opposite of .EQV.. Hence,

to test if logical variables x and y have different values, one can use .NOT. (x .EQV. y). Here, if

x and y have the same value, x .EQV. y is .TRUE. and .NOT. (x .EQV. y) is .FALSE. On the

other hand, if x and y have different values, x .EQV. y is .FALSE. and .NOT. (x .EQV. y) is .TRUE.

  RIORITY P The priority of .NOT. is the highest, followed by .AND., followed by .OR., followed by .EQV.

  and .NEQV. Note that .NOT. is right associative, while the other four are left associative.

  Here are some examples:

  Let LOGICAL variables Something and Another have values .TRUE. and .FALSE.,  respectively.

  .NOT. Something .AND. Another --> .NOT. .TRUE. .AND. .FALSE.

  • > [.NOT. .TRUE.] .AND. .FALSE.
  • > .FALSE. .AND. .FALSE.
  • > .FALSE.

  In the above, since .NOT. has the highest priority, it is evaluated frst. Now, look at the following example: .NOT. (Something .AND. Another)

  • > .NOT. (.TRUE. .AND. .FALSE.)
  • > .NOT. ([.TRUE. .AND. .FALSE.]) --> .NOT. .FALSE.
  • > .TRUE. Let LOGICAL variables a, b and c have values .TRUE., .TRUE. and .FALSE.,

   respectively. .NOT. a .OR. .NOT. b .AND. c --> .NOT. .TRUE. .OR. .NOT. .TRUE. .AND. .FALSE.

  • > [.NOT. .TRUE.] .OR. .NOT. .TRUE. .AND. .FALSE.
  • > .FALSE. .OR. .NOT. .TRUE. .AND. .FALSE.
  • > .FALSE. .OR. [.NOT. .TRUE.] .AND. .FALSE.
  • > .FALSE. .OR. .FALSE. .AND. .FALSE.
  • > .FALSE. .OR. [.FALSE. .AND. .FALSE.] --> .FALSE. .OR. .FALSE.
  • > .FALSE.

  Let INTEGER variable n have a value of 4:

   n**2 + 1 > 10 .AND. .NOT. n < 3

  • > 4**2 + 1 > 10 .AND. .NOT. 4 < 3
  • > [4**2] + 1 > 10 .AND. .NOT. 4 < 3
  • > 16 + 1 > 10 .AND. .NOT. 4 < 3
  • > [16 + 1] > 10 .AND. .NOT. 4 < 3
  • > 17 > 10 .AND. .NOT. 4 < 3
  • > [17 > 10] .AND. .NOT. 4 < 3
  • > .TRUE. .AND. .NOT. 4 < 3
  • > .TRUE. .AND. .NOT. [4 < 3]
  • > .TRUE. .AND. .NOT. .FALSE
  • > .TRUE. .AND. [.NOT. .FALSE] --> .TRUE. .AND. .TRUE.
  • > .TRUE.

  Note that the above expression, if you like, can be rewritten with parentheses as follows: (n**2 + 1 > 10) .AND. .NOT. (n < 3) Let INTEGER variables m, n, x and y have values 3, 5, 4 and 2, respectively:

   .NOT. (m > n .AND. x < y) .NEQV. (m <= n .AND. x >= y)

  • > .NOT. (3 > 5 .AND. 4 < 2) .NEQV. (3 <= 5 .AND. 4 >= 2)
  • > .NOT. ([3 > 5] .AND. 4 < 2) .NEQV. (3 <= 5 .AND. 4 >= 2)
  • > .NOT. (.FALSE. .AND. 4 < 2) .NEQV. (3 <= 5 .AND. 4 >= 2)
  • > .NOT. (.FALSE. .AND. [4 < 2]) .NEQV. (3 <= 5 .AND. 4 >= 2)

  • > .NOT. ([.FALSE. .AND. .FALSE.]) .NEQV. (3 <= 5 .AND. 4 >= 2)
  • > .NOT. (.FALSE.) .NEQV. (3 <= 5 .AND. 4 >= 2)
  • > [.NOT. .FALSE.] .NEQV. (3 <= 5 .AND. 4 >= 2)
  • > .TRUE. .NEQV. (3 <= 5 .AND. 4 >= 2)
  • > .TRUE. .NEQV. ([3 <= 5] .AND. 4 >= 2)
  • > .TRUE. .NEQV. (.TRUE. .AND. 4 >= 2)
  • > .TRUE. .NEQV. (.TRUE. .AND. [4 >= 2])
  • > .TRUE. .NEQV. (.TRUE. .AND. .TRUE.)
  • > .TRUE. .NEQV. ([.TRUE. .AND. .TRUE.])
  • > .TRUE. .NEQV. (.TRUE.) --> .TRUE. .NEQV. .TRUE.
  • > .FALSE.

  SSIGNMENTS A

  The result of a logical expression can be assigned into a LOGICAL variable. Note that only logical values can be put into LOGICAL variables. The follow assignments save the results of the examples into LOGICAL variables: LOGICAL :: Result1, Result2, Result3, Result4 Result1 = .NOT. Something .AND. Another Result2 = .NOT. a .OR. .NOT. b .AND. c Result3 = (n**2 + 1 > 10) .AND. .NOT. (n < 3) Result4 = .NOT. (m > n .AND. x < y) .NEQV. (m <= n .AND. x >= y) Thus, Result1, Result2, Result3 and Results receive .FALSE., .FALSE., .TRUE. and .FALSE., respectively.

IF-THEN-ELSE-END IF

  The most general form of the IF-THEN-ELSE-END IF statement is the following:

  IF (logical-expression) THEN statements-1 ELSE statements-2 END IF where statements-1 and statements-2 are sequences of executable statements, and logical-

  

expression is a logical expression. The execution of this IF-THEN-ELSE-END IF statement

  goes as follows: if the result is .TRUE., the statements in statements-1 are executed  if the result is .FALSE., the statements in statements-2 are executed

    after fnish executing statements in statements-1 or statements-2, the statement following END IF is executed.

  XAMPLES E

  The following code frst reads in an integer into INTEGER variable Number. Then, if 

  Number can be divided evenly by 2 (i.e., Number is a multiple of 2), the WRITE(*,*) between IF and ELSE is executed and shows that the number is even;

  otherwise, the WRITE(*,*) between ELSE and END IF is executed and shows that the number is odd. Function MOD(x,y) computes the remainder of x divided by y. This is the the

  INTEGER :: Number READ(*,*) Number

  IF (MOD(Number, 2) == 0) THEN WRITE(*,*) Number, ' is even' ELSE WRITE(*,*) Number, ' is odd' END IF The following program segment computes the absolute value of X and saves the

   result into variable Absolute_X. Recall that the absolute value of x is x if x is non- negative; otherwise, the absolute value is -x. For example, the absolute value of 5 is 5 and the absolute value of -4 is 4=-(-4). Also note that the WRITE(*,*) statement has been intentionally broken into two lines with thesymbol &. REAL :: X, Absolute_X X = .....

  IF (X >= 0.0) THEN Absolute_X = X ELSE Absolute_X = -X END IF WRITE(*,*) 'The absolute value of ', x, & ' is ', Absolute_X The following program segment reads in two integer values into a and b and fnds  the smaller one into Smaller. Note that the WRITE(*,*) has also been broken into two lines.

  INTEGER :: a, b, Smaller READ(*,*) a, b

  IF (a <= b) THEN Smaller = a ELSE Smaller = b END IF Write(*,*) 'The smaller of ', a, ' and ', & A U SEFUL T

  IP

  You may fnd the following way of organizing IF-THEN-ELSE-END IF very useful, especially when your program logic is reasonably complex.

  

Draw a rectangular box and a vertical line dividing the box into two parts. Then, write down the

logical expression in the left part and draw a horizontal line dividing the right parts into two

smaller ones. The upper rectangle is filled with what you want to do when the logical expression

is .TRUE., while the lower rectangle is filled with what you want to do when the logical expression is .FALSE.:

  what you want to do when the logical expression is .TRUE.

  logical- expression

  what you want to do when the logical expression is .FALSE.

  For example, the third example above has the following description: a is the smaller

  number

  a <= b b is the smaller

  number

  

Although this is an easy example, you will sense its power when you will be dealing with more

complex problems.

IF-THEN-END IF

  The IF-THEN-END IF form is a simplification of the general

   with the ELSE part omitted:

  IF (logical-expression) THEN statements END IF where statements is a sequence of executable statements, and logical-expression is a logical expression. The execution of this IF-THEN-ELSE-END IF statement goes as follows:  the logical-expression is evaluated, yielding a logical value if the result is .TRUE., the statements in statements are executed, followed by the  statement following the IF-THEN-END IF statement. if the result is .FALSE., the statement following the IF-THEN-END IF is executed. In  other words, if logical-expression is .FALSE., there is no action taken.

  E

  XAMPLES

  The following program segment computes the absolute value of X and saves the

   result into variable Absolute_X. Recall that the absolute value of x is x if x is non- negative; otherwise, the absolute value is -x. For example, the absolute value of 5 is 5 and the absolute value of -4 is 4=-(-4). Also note that the WRITE(*,*) statement has been intentionally broken into two lines with thesymbol &. The trick is that the value of X is frst saved to Absolute_X whose value is changed later only if the value of X is less than zero. REAL :: X, Absolute_X X = ..... Absolute_X = X

  IF (X < 0.0) THEN Absolute_X = -X END IF WRITE(*,*) 'The absolute value of ', x, & ' is ', Absolute_X The following program segment reads in two integer values into a and b and fnds  the smaller one into Smaller. Note that the WRITE(*,*) has also been broken into two lines. This uses the same trick discussed in the previous example.

  INTEGER :: a, b, Smaller READ(*,*) a, b Smaller = a

  IF (a > b) THEN Smaller = b END IF Write(*,*) 'The smaller of ', a, ' and ', &

  b, ' is ', Smaller In many cases, it is required to do something when certain condition is satisfed;  otherwise, do nothing. This is exactly what we need the form of IF-THEN-END IF. In the following, an INTEGER variable Counter is used for counting something. When its value is a multiple of 10, a blank line is displayed.

  INTEGER :: Counter

  IF (MOD(Counter, 10) == 0) THEN WRITE(*,*) END IF SEFUL

  IP A U T

  Thecan also be used with this IF-THEN-END IF form. Since there is no ELSE, you can leave the lower part empty like the following: what you want to do when the logical logical- expression is .TRUE.

  expression nothing is here!!!

  IF The logical IF is the simplest form. It has the following form:

  OGICAL L

  IF (logical-expression) one-statement where one-statement is a executable statement which is not another IF, and logical-

  

expression is a logical expression. The execution of this logical IF statement goes as

  follows:  the logical-expression is evaluated, yielding a logical value if the result is .TRUE., the statement in one-statement is executed, followed by the

   statement following the logical IF statement. if the result is .FALSE., the statement following the logical IF is executed. In other

   words, when logical-expression is .FALSE., there is no action taken. Note that this logical IF does have its use although it looks not so powerful comparing with

  

   and

  

  E

  XAMPLES

  The following program segment computes the absolute value of X and saves the  result into variable Absolute_X. Recall that the absolute value of x is x if x is non- negative; otherwise, the absolute value is -x. For example, the absolute value of 5 is 5 and the absolute value of -4 is 4=-(-4). Also note that the WRITE(*,*) statement has been intentionally broken into two lines with thesymbol &. The trick is that the value of X is frst saved to Absolute_X whose value is changed later only if the value of X is less than zero.

  REAL :: X, Absolute_X X = ..... Absolute_X = X

  IF (X < 0.0) Absolute_X = -X WRITE(*,*) 'The absolute value of ', x, & ' is ', Absolute_X

  The following program segment reads in two integer values into a and b and fnds  the smaller one into Smaller. Note that the WRITE(*,*) has also been broken into two lines. This uses the same trick discussed in the previous example.

  INTEGER :: a, b, Smaller READ(*,*) a, b Smaller = a

  IF (a > b) Smaller = b Write(*,*) 'The smaller of ', a, ' and ', &

  b, ' is ', Smaller In many cases, it is required to do something when certain condition is satisfed;  otherwise, do nothing. This is exactly what we need the form of IF-THEN-END IF. In the following, an INTEGER variable Counter is used for counting something. When its value is a multiple of 10, a blank line is displayed.

  INTEGER :: Counter

  IF (MOD(Counter, 10) == 0) WRITE(*,*) The following is wrong since the one-statement if a logical IF can not be another IF statement.

  INTEGER :: a, b, c

  IF (a < b) IF (b < c) WRITE(*,*) a, b, c From the above examples, one can easily see that if the THEN part has exactly one statement and there is no ELSE, the logical IF statement can save some space making a program a little shorter. But, my advice is that don't use it whenever it is possible .

  ROGRAMMING

XAMPLE UADRATIC QUATION OLVER

  P E 1: Q E S ROBLEM TATEMENT P S

  Given a quadratic equation as follows: if b*b-4*a*c is non-negative, the roots of the equation can be solved with the following formulae:

  

Write a program to read in the coefficients a, b and c, and compute and display the roots. If the

discriminant b*b - 4*a*c is negative, the equation has complex root. Thus, this program should

solve the equation if the discriminant is non-negative and show a message otherwise.

  S OLUTION

  ! --------------------------------------------------- ! Solve Ax^2 + Bx + C = 0 given B*B-4*A*C >= 0 ! Now, we are able to detect complex roots.

  ! --------------------------------------------------- PROGRAM QuadraticEquation

  IMPLICIT NONE REAL :: a, b, c REAL :: d REAL :: root1, root2 ! read in the coefficients a, b and c READ(*,*) a, b, c WRITE(*,*) 'a = ', a WRITE(*,*) 'b = ', b WRITE(*,*) 'c = ', c WRITE(*,*) ! compute the square root of discriminant d d = b*b - 4.0*a*c

  IF (d >= 0.0) THEN ! is it solvable? d = SQRT(d) root1 = (-b + d)/(2.0*a) ! first root root2 = (-b - d)/(2.0*a) ! second root WRITE(*,*) 'Roots are ', root1, ' and ', root2 ELSE ! complex roots WRITE(*,*) 'There is no real roots!' WRITE(*,*) 'Discriminant = ', d END IF END PROGRAM QuadraticEquation Clito download this program.

  I O

  ROGRAM NPUT AND UTPUT P

  If the input to the program consists of 1.0, 5.0 and 2.0, we have the following output.  Since the discriminant is b*b - 4.0*a*c = 5.0*5.0 - 4.0*1.0*2.0 = 17.0 > 0.0, the THEN part is executed and the real roots are -0.438447237 and -4.561553.

  1.0 5.0 2.0 a = 1. c = 2. Roots are -0.438447237 and -4.561553 If the input to the program consists of 1.0, 2.0 and 5.0, we have the following output.  Since the discriminant is b*b - 4.0*a*c = 2.0*2.0 - 4.0*1.0*5.0 = -16.0 < 0.0, the

  ELSE part is executed and a message of no real roots is displayed followed the value of the discriminant.

  1.0 2.0 5.0 a = 1. b = 2. c = 5. There is no real roots! Discriminant = -16.

  ISCUSSION D

  Here is theof this program. Note that information in diferent parts of the box do not have to be very precise. As long as it can tell what to do, it would be sufcient. computes the real roots

  b*b - 4.0*a*c >= 0.0

  there is no real roots

  ROGRAMMING

  XAMPLE

INAL ARK OMPUTATION

  P E 2: F M C P ROBLEM S TATEMENT

Two examination papers are written at the end of the course. The final mark is either the average

of the two papers, or the average of the two papers and the class record mark (all weighted equally), whichever is the higher. The program should reads in the class record mark and the marks of the papers, computes the average, and shows PASS (>= 50%) or FAIL (< 50%).

  OLUTION S

  ! ------------------------------------------------------------- ! Two examination papers are written at the end of the course. ! The final mark is either the average of the two papers, or ! the average of the two papers and the class record mark (all ! weighted equally), whichever is the higher. The program ! should reads in the class record mark and the marks of the

  ! FAIL (< 50%). ! ------------------------------------------------------------- PROGRAM FinalMark

  IMPLICIT NONE REAL :: Mark1, Mark2 ! the marks of the papers REAL :: Final ! the final marks REAL :: ClassRecordMark ! the class record mark REAL, PARAMETER :: PassLevel = 50.0 ! the pass level READ(*,*) ClassRecordMark, Mark1, Mark2 Final = (Mark1 + Mark2) / 2.0

  IF (Final <= ClassRecordMark) THEN Final = (Mark1 + Mark2 + ClassRecordMark) / 3.0 END IF WRITE(*,*) 'Class Record Mark : ', ClassRecordMark WRITE(*,*) 'Mark 1 : ', Mark1 WRITE(*,*) 'Mark 2 : ', Mark2 WRITE(*,*) 'Final Mark : ', Final

  IF (Final >= PassLevel) THEN WRITE(*,*) 'Pass Status : PASS' ELSE WRITE(*,*) 'Pass Status : FAIL' END IF END PROGRAM FinalMark Clito download this program.

  I O

  ROGRAM NPUT AND UTPUT P

  If the input to class record mark, the mark of the frst paper, and the mark of the  second paper are 40.0, 60.0 and 43.0, the average is (60.0 + 43.0)/2 = 51.5, which is larger than the class record mark (40.0). Therefore, this student has a fnal mark 51.5 and receives a PASS status.

  40.0 60.0 43.0 Class Record Mark : 40. Mark 1 : 60. Mark 2 : 43. Final Mark : 51.5 Pass Status : PASS If the input to class record mark, the mark of the frst paper, and the mark of the

   second paper are 60.0, 45.0 and 43.0, then the average is (45.0 + 43.0)/2 = 44.0, which is less than the class record mark (60.0). Therefore, this student's new mark is the average of his marks and the class record mark, (60.0 + 45.0 + 43.0)/3.0 = 49.33333. Since this new mark is less than 50.0, this student receives a FAIL status.

  Class Record Mark : 60. Mark 1 : 45. Mark 2 : 43. Final Mark : 49.3333321 Pass Status : FAIL

  ISCUSSION D

  The READ statement reads in values for ClassRecordMark, Mark1 and Mark2.  The average of papers is computed and stored in Final  If this fnal mark is less than or equal to the class record mark, a new fnal mark is

   computed as the average of the two marks and the class record mark. Here, the IF-

  THEN-END form is used. You can use the logical IF form; but, this line could be too long. As mentioned earlier, the IF-THEN-END IF is preferred.

  The four WRITE(*,*) statements display the input and the computed fnal mark.

   Finally, the IF-THEN-ELSE-END IF determines if the fnal mark is a pass or a fail. 

  ROGRAMMING

  XAMPLE ERON S ORMULA FOR OMPUTING P E 3: H ' F C

  RIANGLE REA T A ROBLEM TATEMENT P S

Given a triangle with side lengths a, b and c, its area can be computed using the Heron's formula: where s is the half of the perimeter length: Write a program to read in the coefficients a, b and c, and compute the area of the triangle. However, not any three numbers can make a triangle. There are two conditions. First, all side lengths must be positive: and second the sum of any two side lengths must be greater than the third side length: In the program, these two conditions must be checked before computing the triangle area; otherwise, square root computation will be in trouble.

  S OLUTION

  ! ------------------------------------------------------ ! Compute the area of a triangle using Heron's formula ! ------------------------------------------------------ PROGRAM HeronFormula

  IMPLICIT NONE REAL :: a, b, c ! three sides REAL :: s ! half of perimeter REAL :: Area ! triangle area LOGICAL :: Cond_1, Cond_2 ! two logical conditions READ(*,*) a, b, c WRITE(*,*) "a = ", a WRITE(*,*) "b = ", b WRITE(*,*) "c = ", c WRITE(*,*) Cond_1 = (a > 0.) .AND. (b > 0.) .AND. (c > 0.0) Cond_2 = (a+b > c) .AND. (a+c > b) .AND. (b+c > a)

  IF (Cond_1 .AND. Cond_2) THEN s = (a + b + c) / 2.0 Area = SQRT(s*(s-a)*(s-b)*(s-c)) WRITE(*,*) "Triangle area = ", Area ELSE WRITE(*,*) "ERROR: this is not a triangle!" END IF END PROGRAM HeronFormula Clito download this program.

  I O

  ROGRAM NPUT AND UTPUT P

  If the input to the program consists of 3.0, 5.0 and 7.0, we have the following output.  Since the value of all input are positive and the sum of any two is larger than the third (i.e., 3.0+5.0 > 7.0, 3.0+7.0+5.0 and 5.0+7.0>3.0), both conditions hold and the program can compute the area of the triangle. The area is 6.49519062.

  3.0 5.0 7.0 a = 3. b = 5.

  Triangle area = 6.49519062 If the input to the program consists of 3.0, 4.0 and 7.0, we have the following output.  Although all input values are positive, this is not a triangle since the sum of the frst side (3.0) and the second (4.0) is not grater than the third (8.0). The program generates an error message.

  3.0 4.0 8.0 a = 3. b = 4. c = 8. ERROR: this is not a triangle! If the input to the program consists of -1.0, 3.0 and 5.0, we have the following output.

   Since not all input values are positive, this is not a triangle.

  • 1.0 3.0 5.0 a = -1. b = 3. c = 5. ERROR: this is not a triangle!

  ISCUSSION D

  This program uses two LOGICAL variables, Cond_1 and Cond_2 to store the results

   of the two conditions. The conditions are checked with the frst two assignments.

   Since all side lengths must be greater than zero, operator .AND. are used to connect  a > 0.0, b > 0.0 and c > 0.0. Since the sum of any two side lengths must be greater than the third side length, all  three comparisons must be .TRUE. and operator .AND. is used. Since both conditions must be true in order to have a triangle, .AND. is also used in

   the IF-THEN-ELSE-END IF statement. If both conditions are .TRUE., the THEN part is executed, where the value of s and

   the area is computed and displayed. If one or both conditions is .FALSE., the input is not a triangle and an error message

   is displayed. You can pull all six comparisons into a single logical expression. But, this expression

   could be too long to be ft into a single line. While continuation line can be used, it may not be readable. So, I prefer to have separate lines. Here is theof this program.

  

a, b and c form a computes s and its

  triangle area displays an error message

IF-THEN-ELSE-END IF

  ESTED N

  

The THEN part and the ELSE part, if any, can contain one or more IF-THEN-ELSE-END IF

statement in one of the three forms. That is, when you feel it is necessary, you can use as many

  IF-THEN-ELSE-END IF statements in the THEN part and the ELSE part as you want.

  However, please note that any such IF-THEN-ELSE-END IF must be fully contained in the THEN part or the ELSE part. If you follow thehis requirement is automatically satisfied. The following is an example:

  IF (logical-expression) THEN statements

  IF (logical-expression) THEN statements ELSE statements END IF statements ELSE statements

  IF (logical-expression) THEN statements END IF statements END IF

  E

  XAMPLES

  Suppose we need a program segment to read a number x and display its sign. More  precisely, if x is positive, a + is displayed; if x is negative, a - is displayed; otherwise, a 0 is displayed. With an IF-THEN-ELSE-END IF statement, we have a two-way decision (i.e., true or false). What we need is a tree-way decision and some trick is required. In this case, thecan be very helpful.

  Let us start testing if x is positive. What we get is the following:

  display +

  x >

  one down (i.e., +) two to go (i.e.,

  • - and 0)
In the lower part, no decision can been reached. What we want to know is finding out is x

is zero or negative (x cannot be positive here since it has been ruled out in the upper

part). To determine whether a - or a 0 should be displayed, one more decision is required:

  display -

  x <

  display 0)

  

Since this is the work for the lower rectangle, let us put it there yielding the following:

  display + display

  x >

  • -

    x <

  display

  Converting to a IF-THEN-ELSE-END IF construct is easy since the above box is almost identical to that. So, here is our answer:

  IF (x > 0) THEN WRITE(*,*) '+' ELSE

  IF (x < 0) THEN WRITE(*,*) '-' ELSE WRITE(*,*) '0' END IF END IF Given a x, we want to display the value of -x if x < 0, the value of x*x if x is in the  range of 0 and 1 inclusive, and the value of 2*x if x is greater than 1.

  Obviously, this problem cannot be solved with a two-way IF and the box trick becomes useful. Let us start with x<0.

  display -x

  x <

  here we have x

  >= 0

For the x >= 0 part, x may be in the range of 0 and 1; if not, x must be greater than 1

since x cannot be less than 0. Therefore, we have the following box for the case of x >=

  x is in the range of 0 and 1.

  display x*x

  x <=

  1

  here we have x > 1. display

  2*x Inserting this box into the previous one yields the following final result:

  display -x display

  x < x*x x <=

  1

  display

  2*x Converting to using IF, we have the following:

  IF (x < 0) THEN WRITE(*,*) -x ELSE

  IF (x <= 1) THEN WRITE(*,*) x*x ELSE WRITE(*,*) 2*x END IF END IF Given three numbers a, b and c, we want to fnd out the smallest one. 

  

There are many solutions to this problem; but, we shall use the box trick again. Let us

pick two numbers, say a and b. Thus, we get the following:

a has the potential to be the smallest

a <

b since b <= a, b has the potential to be

  the smallest

  Now we know a possible smallest number. To find the real smallest one, this "possible" number must be compared against c. If the possible one is a (the upper part), we need to do the following: a < a is the smallest c

  since c <= a and b <= a, c is the smallest

  Let us turn to the lower part, where b has the potential to be the smallest. Comparing with c yields: b is the smallest b <

c since c <= b and b <= a, c is