• Tidak ada hasil yang ditemukan

LOGICAL Type and Variables

N/A
N/A
Protected

Academic year: 2018

Membagikan "LOGICAL Type and Variables"

Copied!
48
0
0

Teks penuh

(1)

S

ELECTIVE

E

XECUTION

S

ELECT THE TOPICS YOU WISH TO REVIEW

:

Selective Execution

LOGICAL Type and Variables

LOGICAL Input and Output

Relational Operators

LOGICAL Operators and Expressions IF-THEN-ELSE-END IF Statement Form 1: IF-THEN-ELSE-END IF

Form 2: IF-THEN-END IF

Form 3: Logical IF

Programming Example 1: Quadratic Equation Solver

Programming Example 2: Final Mark Computation

Programming Example 3: Heron's Formula for Computing Triangle Area

Nested IF-THEN-ELSE-END IF

IF-THEN-ELSE IF-END IF Programming Examples: Quadratic Equation Solver: Again

Quadratic Equation Solver: Revisited

Sort Three Numbers

SELECT CASE Statement

Programming Example 1: Computing Letter Grade

Programming Example 2: Character Testing

(2)

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

(3)

LOGICAL INPUT AND OUTPUT

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.

RELATIONAL OPERATORS

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:

Type Operator Associati vity

Arithme tic

(4)

Relation

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*d

expressions 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*b

is 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 use logical operator to achieve this.

E

XAMPLES

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.

(5)

--> 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 /=

C

OMPARING

CHARACTER S

TRINGS

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.

(6)

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.

A S

PECIAL

N

OTE

The priority of all six relational operators is lower than the string concatenation operator //. 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.

(7)

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

arithmetic and relational operators. 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.

Type Operator Associati vity

Arithme tic

** right to left

* / left to right + - left to right Relation

al

<< =

>> =

=

= /= none

Logical

.NOT. right to left

.AND. left to right .OR. left to right .EQV. .NEQV. left to right

T

RUTH

T

ABLES

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

.NO T.

Opera nd

(8)

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.:

.AND. .TRU

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.:

.OR. .TRU

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.

(9)

.EQV. .TRU

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

relational expressions, 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

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 in relational expressions, 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.

P

RIORITY

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:

(10)

.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.

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:

(11)

--> .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.

A

SSIGNMENTS

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 logical-expression. The execution of this IF-THEN-ELSE-END IF statement goes as follows:

(12)

 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.

E

XAMPLES

 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 remainder (or modulo) function

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 the continuation line symbol &.

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

(13)

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.:

logical-expression

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

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

For example, the third example above has the following description:

a <= b

a is the smaller number

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 IF-THEN-ELSE-END IF form

with the ELSE part omitted:

IF (logical-expression) THEN statements

(14)

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 the continuation line symbol &. 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(*,*)

(15)

A U

SEFUL

T

IP

The box trick can 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:

logical-expression

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

nothing is here!!!

L

OGICAL

IF

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

IF (logical-expression) one-statement

where one-statement is a executable statement which is not another IF, and logical-expression is a logical 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

IF-THEN-ELSE-END IF and IF-THEN-END IF.

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 the continuation line symbol &. 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

(16)

 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.

PROGRAMMING EXAMPLE 1: QUADRATIC EQUATION SOLVER

P

ROBLEM

S

TATEMENT

Given a quadratic equation as follows:

(17)

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

Click here to download this program.

P

ROGRAM

I

NPUT AND

O

UTPUT

 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

(18)

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.

D

ISCUSSION

Here is the box trick of 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.

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

computes the real roots

there is no real roots

PROGRAMMING EXAMPLE 2: FINAL MARK COMPUTATION

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%).

S

OLUTION

(19)

! 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

Click here to download this program.

P

ROGRAM

I

NPUT AND

O

UTPUT

 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.

(20)

Class Record Mark : 60. Mark 1 : 45. Mark 2 : 43.

Final Mark : 49.3333321 Pass Status : FAIL

D

ISCUSSION

 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.

P

ROGRAMMING

E

XAMPLE

3: H

ERON

'

S

F

ORMULA

FOR

C

OMPUTING

T

RIANGLE

A

REA

P

ROBLEM

S

TATEMENT

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:

(21)

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

Click here to download this program.

P

ROGRAM

I

NPUT AND

O

UTPUT

 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

(22)

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!

D

ISCUSSION

 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 the box trick of this program.

a, b and c form a triangle

(23)

displays an error message

NESTED IF-THEN-ELSE-END IF

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 the box trick, this 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, the box trick can be very helpful.

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

x > 0

display +

(24)

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:

x < 0

display

-display 0)

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

x > 0

display +

x < 0

display - display 0

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.

x < 0

display -x

here we have x >= 0

(25)

x <= 1

x is in the range of 0 and 1. display x*x

here we have x > 1. display 2*x

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

x < 0

display -x

x <= 1

display x*x 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 < b

a has the potential to be the smallest 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 < c

a is the smallest

(26)

the smallest

Let us turn to the lower part, where b has the potential to be the smallest. Comparing with

c yields:

b < c

b is the smallest

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

Inserting the above two boxes into the first one yields the following complete solution:

a < b

a < c

the smallest is a

the smallest is c

b < c

the smallest is b

the smallest is c

Converting to the IF version, we have

IF (a < b) THEN IF (a < c) THEN Result = a ELSE

Result = c END IF

ELSE

IF (b < c) THEN Result = b ELSE

Result = c END IF

END IF

WRITE(*,*) 'The smallest is ', Result

The above code segment uses variable Result to hold the smallest value.

(27)

The Nested IF-THEN-ELSE-END IF statement could produce a deeply nested IF statement

which is difficult to read. There is a short hand to overcome this problem. It is the

IF-THEN-ELSE IF-END-IF version. Its syntax is shown below:

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

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

ELSE IF (logical-expression-3) THEN statement-3

ELSE IF (...) THEN ...

ELSE

statements-ELSE END IF

Fortran evaluates logical-expression-1 and if the result is .TRUE., statements-1 is executed followed by the statement after END IF. If logical-expression-1 is .FALSE., Fortran evaluates logical-expression-2 and executes statements-2 and so on. In general, if logical-expression-n is .TRUE., statements-n is executed followed by the statement after END IF; otherwise, Fortran continues to evaluate the next logical expression.

If all logical expressions are .FALSE. and if ELSE is there, Fortran executes the

statements-ELSE

; otherwise, Fortran executes the statement after the END IF.

Note that the statements in the THEN section, ELSE IF section, and ELSE section can be

another IF statement.

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. Here is a possible solution using IF-THEN-ELSE IF-END IF:

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

WRITE(*,*) '-' 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.

The following is a possible solution:

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

(28)

END IF

 Consider the following code segment:

INTEGER :: x CHARACTER(LEN=1) :: Grade

IF (x < 50) THEN Grade = 'F'

ELSE IF (x < 60) THEN Grade = 'D'

ELSE IF (x < 70) THEN Grade = 'C'

ELSE IF (x < 80) THEN Grade = 'B'

ELSE

Grade = 'A' END IF

First, if x is less than 50, 'F' is assigned to Grade. If x is greater than or equal to 50, the execution continue with the frst ELSE IF where x < 60 is tested. If it is .TRUE., 'D' is assigned to Grade. Note that one can reach the test of x < 60 simply because the test x < 50 is .FALSE.. Therefore, when reaches x < 60, we are sure that x >= 50 must hold and as a result, Grade receives 'D' if x is greater than or equal to 50 and is less than 60.

By the same token, we know that if x is greater than or equal to 60 and is less than 70,

Grade receives 'C'. If x is greater than or equal to 70 and is less than 80, Grade receives

'B'. Finally, if x is greater than or equal to 80, Grade receives 'A'.

The frst and second examples show that IF-THEN-ELSE IF-END IF can save some space and at the same time make a program more readable. Compare these two solutions with those using nest IF.

Note also that not all nested IF can be converted to the IF-THEN-ELSE IF-ELSE-END-IF

form. For example, the example of determining the smallest of three numbers cannot be

converted immediately. In general, if all tests (

i.e.

, logical expressions) are mutually exclusive,

then the chance to have a successful conversion is high. Otherwise, rewriting some parts or

combining logical expression can be helpful. Here is one more example:

Let us reconsider the problem of finding the smallest of three given numbers. We know that if a

is the smallest, then it must be smaller than the other two. Moreover, the condition for a number

being the smallest is mutually exclusive. Thus, we have a successful conversion as follows:

IF (a < b .AND. a < c) THEN Result = a

ELSE IF (b < a .AND. b < c) THEN Result = b

ELSE

(29)

Q

UADRATIC

E

QUATION

S

OLVER

- A

GAIN

P

ROBLEM

S

TATEMENT

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 solve the equation. Note that a

quadratic equation has repeated root if b*b-4.0*a*c is equal to zero. This program should

distinguish repeated roots from distinct roots.

S

OLUTION

! ---! Solve Ax^2 + Bx + C = 0 given B*B-4*A*C >= 0 ! Now, we are able to detect complex roots and ! repeated 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(*,*)

(30)

d = b*b - 4.0*a*c

IF (d > 0.0) THEN ! distinct roots? 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

IF (d == 0.0) THEN ! repeated roots? WRITE(*,*) 'The repeated root is ', -b/(2.0*a) ELSE ! complex roots

WRITE(*,*) 'There is no real roots!' WRITE(*,*) 'Discriminant = ', d END IF

END IF

END PROGRAM QuadraticEquation

Click here to download this program.

P

ROGRAM

I

NPUT AND

O

UTPUT

 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. b = 5. c = 2.

Roots are -0.438447237 and -4.561553

 If the input to the program consists of 1.0, -10.0 and 25.0, we have the following output. Since the discriminant is b*b - 4.0*a*c = (-10.0)*(-10.0) - 4.0*1.0*25.0 = 0.0, the ELSE part is executed. Since there is a nested IF-THEN-ELSE-END IF in the ELSE, d = 0.0 is tested and therefore yields a repeated root 5.

1.0 -10.0 25.0

a = 1. b = -10. c = 25.

The repeated root is 5.

 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. Since d < 0.0, the ELSE part of the inner IF-THEN-ELSE-END IF is executed and a message of no real roots is displayed followed by the value of the discriminant.

1.0 2.0 5.0

(31)

c = 5.

There is no real roots! Discriminant = -16.

D

ISCUSSION

Here is the box trick of this program.

b*b - 4.0*a*c > 0.0

computes the real roots

repeated root or no real root

The lower part is not complete yet since we do not know if the equation has a repeated root.

Therefore, one more test is required:

b*b - 4.0*a*c = 0.0

computes the repeated root

no real root

Inserting this back to the original yields the following final result:

b*b - 4.0*a*c > 0.0

computes the real roots

b*b - 4.0*a*c = 0.0

compute the repeated root

no real root

This is the logic used in the above program.

The following is an equivalent program that uses ELSE-IF construct rather than nested IF:

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

!

(32)

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 discriminant d

d = b*b - 4.0*a*c

IF (d > 0.0) THEN ! distinct roots? 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 IF (d == 0.0) THEN ! repeated roots? WRITE(*,*) 'The repeated root is ', -b/(2.0*a) ELSE ! complex roots WRITE(*,*) 'There is no real roots!'

WRITE(*,*) 'Discriminant = ', d END IF

END PROGRAM QuadraticEquation

Click here to download this program.

Its logic is shown below using the box trick.

b*b - 4.0*a*c ? 0.0

>computes the real roots

=computes the repeated root

>

no real root

(33)

P

ROBLEM

S

TATEMENT

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 solve the equation. Note that a

quadratic equation has repeated root if b*b-4.0*a*c is equal to zero.

However, if a is zero, the equation becomes a linear one whose only solution is -c/b if b is not

zero. Otherwise, if b is zero, two cases are possible. First, if c is also zero, any number can be a

solution because all three coefficients are zero. Otherwise, the equation c = 0 cannot have any

solution.

This program should handle

all

cases.

S

OLUTION

! ---! Solve Ax^2 + Bx + C = 0 given B*B-4*A*C >= 0 ! Now, we are able to detect the following: ! (1) unsolvable equation

! (2) linear equation ! (3) quadratic equation ! (a) distinct real roots ! (b) repeated root

! (c) no real roots

!

---PROGRAM QuadraticEquation IMPLICIT NONE

REAL :: a, b, c REAL :: d

REAL :: root1, root2

! read in the coefficients a, b and c

(34)

WRITE(*,*) 'a = ', a WRITE(*,*) 'b = ', b WRITE(*,*) 'c = ', c WRITE(*,*)

IF (a == 0.0) THEN ! could be a linear equation IF (b == 0.0) THEN ! the input becomes c = 0 IF (c == 0.0) THEN ! all numbers are roots WRITE(*,*) 'All numbers are roots'

ELSE ! unsolvable WRITE(*,*) 'Unsolvable equation' END IF

ELSE ! linear equation

WRITE(*,*) 'This is linear equation, root = ', -c/b END IF

ELSE ! ok, we have a quadratic equation d = b*b - 4.0*a*c

IF (d > 0.0) THEN ! distinct roots? 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 IF (d == 0.0) THEN ! repeated roots? WRITE(*,*) 'The repeated root is ', -b/(2.0*a) ELSE ! complex roots

WRITE(*,*) 'There is no real roots!' WRITE(*,*) 'Discriminant = ', d END IF

END IF

END PROGRAM QuadraticEquation

Click here to download this program.

P

ROGRAM

I

NPUT AND

O

UTPUT

Since we have been doing the quadratic part in several similar examples, the following concentrates on the order part of the program.

 If the input to the program consists of 0.0, 1.0 and 5.0, we have the following output. Since a is zero, this could be a linear equation. Since b=1.0, it is a linear equation 1.0*x + 5.0 = 0.0 with the only root -5.0/2.0=-5.0.

0.0 1.0 5.0

a = 0.E+0 b = 1. c = 5.

This is linear equation, root = -5.

 If the input to the program consists of 0.0, 0.0 and 0.0, we have the following output. Since all coefcients are zero, any number is a root.

(35)

a = 0.E+0 b = 0.E+0 c = 0.E+0

All numbers are roots

 If the input to the program consists of 0.0, 0.0 and 4.0, we have the following output. Since the equation becomes 4.0 = 0.0, which is impossible. Therefore, this is not a solvable equation.

0.0 0.0 4.0

a = 0.E+0 b = 0.E+0 c = 4.

Unsolvable equation

D

ISCUSSION

Here is the box trick of this program. It is more complex than all previous versions of quadratic equation solvers.

Let us start with linear equations.

a = 0

it could be a linear equation

a quadratic equation

Since we have learned to do the quadratic part, we shall do the linear equation part first. To be a

linear equation, b cannot be zero and this has to be addressed in the upper rectangle:

a = 0

b = 0

need to know if c is zero

the equation is linear b*x+c=0

a quadratic equation

If c is zero, then every number is a root and we have:

a = 0

b = 0 c =

0

every number is a root

this equation is not solvable

(36)

b*x+c=0 a quadratic equation

To complete the bottom rectangle, let us take the box from previous example. The final result is:

a = 0

b = 0

c = 0

every number is a root

this equation is not solvable

the equation is linear b*x+c=0

b*b -4.0*a*c ? 0.0

> computes the real roots

= computes the repeated root

> no real root

The above program is written based on this logic.

S

ORT

T

HREE

N

UMBERS

P

ROBLEM

S

TATEMENT

Give three integers, display them in ascending order. For example, if the input is 2, 3 and 1, this

program should display 1, 2 and 3.

S

OLUTION

! ---! This program reads in three INTEGERs and displays them ! in ascending order.

!

---PROGRAM Order IMPLICIT NONE

(37)

READ(*,*) a, b, c

IF (a < b) THEN ! a < b here

IF (a < c) THEN ! a < c : a the smallest IF (b < c) THEN ! b < c : a < b < c WRITE(*,*) a, b, c

ELSE ! c <= b : a < c <= b WRITE(*,*) a, c, b

END IF

ELSE ! a >= c : c <= a < b WRITE(*,*) c, a, b

END IF

ELSE ! b <= a here

IF (b < c) THEN ! b < c : b the smallest IF (a < c) THEN ! a < c : b <= a < c WRITE(*,*) b, a, c

ELSE ! a >= c : b < c <= a WRITE(*,*) b, c, a

END IF

ELSE ! c <= b : c <= b <= a WRITE(*,*) c, b, a

END IF END IF

END PROGRAM Order

Click here to download this program.

D

ISCUSSION

This is a good example for using the box trick. The main idea is that if we know the smallest number, then one comparison between the remaining two would give the second smallest and the largest number. Finding the smallest of three numbers has been discussed in

nested IF .

So, let us start with a:

a < b

a may be the smallest

b may be the smallest

For the upper rectangle, we need to know if a is less than c, while for the lower rectangle we

need to know if b is less than c:

a < b

a < c

(38)

c <= a < b here, sorted!!!

b < c

b is the smallest, relation between a and c unknown

c <= b <= a here, sorted!!!

For the top rectangle, we need one more comparison b < c and for the rectangle on the third row

we need a < c. The following is our final result:

a < Here is the box diagram:

(39)

< b b here

c < b <= a here

Converting this diagram to IF-THEN-ELSE IF we have the following:

! ---! This program reads in three INTEGERs and displays them ! in ascending order.

!

---PROGRAM Order IMPLICIT NONE

INTEGER :: a, b, c

READ(*,*) a, b, c

IF (a <= b .AND. a <= c) THEN ! a the smallest IF (b <= c) THEN ! a <= b <= c WRITE(*,*) a, b, c

ELSE ! a <= c <= b WRITE(*,*) a, c, b

END IF

ELSE IF (b <= a .AND. b <= c) THEN ! b the smallest IF (a <= c) THEN ! b <= a <= c WRITE(*,*) b, a, c

ELSE ! b <= c <= a WRITE(*,*) b, c, a

END IF

ELSE ! c the smallest IF (a <= b) THEN ! c <= a <= b WRITE(*,*) c, a, b

ELSE ! c <= b <= a WRITE(*,*) c, b, a

END IF END IF

END PROGRAM Order

Click here to download this program.

SELECT CASE STATEMENT

(40)

SELECT CASE (selector) CASE (label-list-1) statements-1 CASE (label-list-2) statements-2 CASE (label-list-3) statements-3 ... CASE (label-list-n) statements-n CASE DEFAULT

statements-DEFAULT END SELECT

where statements-1, statements-2, statements-3, ..., statements-n and statements-DEFAULT are sequences of executable statements, including the SELECT CASE statement itself, and selector is an expression whose result is of type INTEGER, CHARACTER or LOGICAL (i.e., no REAL type can be used for the selector). The label lists 1, 2, label-list-3, ..., and label-list-n are called case labels.

A label-list is a list of labels, separated by commas. Each label must be one of the following

forms. In fact, three of these four are identical to an

extent specifier

for substrings:

value

value-1 : value-2 value-1 :

: value-2

where value, value-1 and value-2 are constants or alias defned by PARAMETER. The type of these constants must be identical to that of the selector.

The frst form has only one value

The second form means all values in the range of value-1 and value-2. In this form, value-1 must be less than value-2.

The third form means all values that are greater than or equal to value-1

The fourth form means all values that are less than or equal to value-2

The rule of executing the SELECT CASE statement goes as follows: The selector expression is evaluated

If the result is in label-list-i, then the sequence of statements in statements-i are executed, followed by the statement following END SELECT

If the result is not in any one of the label lists, there are two possibilities:

o if CASE DEFAULT is there, then the sequence of statements in statements-DEFAULT are executed, followed by the statement following END SELECT

o if there is no CASE DEFAULT is not there, the statement following END SELECT is executed.

(41)

CASE DEFAULT is optional. But with a CASE DEFAULT, you are guaranteed that whatever the selector value, one of the labels will be used. I strongly suggest to add a CASE DEFAULT in every SELECT CASE statement.

The place for CASE DEFAULT can be anywhere within a SELECT CASE statement; however, put it at the end would be more natural.

E

XAMPLES

The following uses Class to execute a selection. If Class is 1, Freshman is

displayed; if Class is 2, Sophomore is displayed; if Class is 3, Junior is displayed; if

Class is 4, Senior is displayed; and if Class is none of the above, Hmmmm, I don't know is displayed. After displaying one of the above, Done is displayed.

INTEGER :: Class

In the following, the value of CHARACTER variable Title is used as a selector. If its value is "DrMD" (resp., "PhD", "MS" and "BS"), then INTEGER variables DrMD

The follow example does not use CASE DEFAULT since the label lists have already covered all possibilities. If the value of Number is less than or equal to -1 (:-1), -1 is stored into Sign. If the value of Number is zero, 0 is stored into Sign. If the value of

Number is greater than or equal to 1, 1 is stored into Sign.

(42)

SELECT CASE (Number)

characters, which may not be letters' is displayed. In the last case, the value of c

could be one of these lower case letters not listed, an upper case letters, a digit, an operator, or any other character. So, if you only want to handle lower case letters, this program is incorrect.

CHARACTER(LEN=1) :: c

The following program uses the value of Number to determine the value of Range.

INTEGER :: Number, Range

Here is the result:

(43)

e

<= -10 1 CASE ( : -10, 10 : )

-9, -8, -7,

-6 6 CASE DEFAULT

-5, -4, -3 2 CASE (-5:-3, 6:9)

-2, -1, 0,

1, 2 3 CASE (-2:2)

3 4 CASE (3, 5)

4 5 CASE (4)

5 4 CASE (3, 5)

6, 7, 8, 9 2 CASE (-5:-3, 6:9)

>= 10 1 CASE ( : -10, 10 : )

P

ROGRAMMING

E

XAMPLE

1: L

ETTER

G

RADE

C

OMPUTATION

P

ROBLEM

S

TATEMENT

At the end of a quarter, the average of three marks must be computed. Then, this average is

rounded and used to determine the corresponding letter grade. The letter grades are computed as

follows:

Range Grad e >= 90 A

< 90 and

>= 85 AB

(44)

>= 80

< 80 and

>= 75 BC

< 75 and >= 70 C

< 70 and

>= 65 CD

< 65 and >= 60 D

< 60 F

Write a program to read three marks, compute its average, round the average and use it to

determine the corresponding letter grade.

S

OLUTION

! ---! This program reads three marks, computes their average ! and determines the corresponding letter grade with ! the following table:

!

! A : average >= 90 ! AB : 85 <= average < 90 ! B : 80 <= average < 84 ! BC : 75 <= average < 79 ! C : 70 <= average < 74 ! CD : 65 <= average < 69 ! D : 60 <= average < 64 ! F : average < 60

!

! where 'average' is the rounded average of the three ! marks. More precisely, if the average is 78.6, then it ! becomes 79 after rounding; or, if the average is 78.4, ! it becomes 78 after truncating.

!

---PROGRAM LetterGrade IMPLICIT NONE

REAL :: Mark1, Mark2, Mark3 REAL :: Average

CHARACTER(LEN=2) :: Grade

READ(*,*) Mark1, Mark2, Mark3

(45)

SELECT CASE (NINT(Average)) ! round Average before use CASE (:59) ! <= 59 ---> F Grade = 'F '

CASE (60:64) ! >= 60 and <= 64 ---> D Grade = 'D '

CASE (65:69) ! >= 65 and <= 69 ---> CD Grade = 'CD'

CASE (70:74) ! >= 70 and <= 74 ---> C Grade = 'C '

CASE (75:79) ! >= 75 and <= 79 ---> BC Grade = 'BC'

CASE (80:84) ! >= 80 and <= 84 ---> B Grade = 'B '

CASE (85:89) ! >= 84 and <= 89 ---> AB Grade = 'AB'

CASE DEFAULT ! >= 90 ---> A Grade = 'A '

END SELECT

WRITE(*,*) 'First Mark : ', Mark1 WRITE(*,*) 'Second Mark : ', Mark2 WRITE(*,*) 'Third Mark : ', Mark3 WRITE(*,*) 'Average : ', Average WRITE(*,*) 'Letter Grade : ', Grade

END PROGRAM LetterGrade

Click here to download this program.

P

ROGRAM

I

NPUT AND

O

UTPUT

 The following output is generated from input 97.0, 90.0 and 94.0. The average is 93.66666641. The result after rounding is 94 and hence the letter grade is an A.

97.0 90.0 94.0

First Mark : 97. Second Mark : 90. Third Mark : 94.

Average : 93.6666641 Letter Grade : A

 The following output is generated from input 92.0, 85.0 and 83.0. The average is 86.6666641. The result after rounding is 87 and hence the letter grade is an AB.

92.0 85.0 83.0

First Mark : 92. Second Mark : 85. Third Mark : 83.

Average : 86.6666641 Letter Grade : AB

(46)

75.0 60.0 45.0

First Mark : 75. Second Mark : 60. Third Mark : 45. Average : 60. Letter Grade : D

D

ISCUSSION

This is an easy example and only one place requires further explanation. The concept of rounding is converting a real number to its nearest integer. Therefore, after rounding, 4.5 and 4.4 become 5 and 4, respectively. Moreover, after rounding, -4.5 and -4.4 become -5 and -4, respectively. The Fortran intrinsic function for rounding is NINT(), which was discussed in Fortran intrinsic functions.

(47)

P

ROGRAMMING

E

XAMPLE

2: C

HARACTER

T

ESTING

P

ROBLEM

S

TATEMENT

This is an extension of an example discussed in SELECT CASE statement. This program reads

in a character and determines if it is a vowel, a consonant, a digit, one of the four arithmetic

operators, a space, or something else (

i.e.

, %, $, @, etc).

S

OLUTION

! ---! This program reads in a single character and determines if ! it is a vowel, a consonant, a digit, one of the four

! arithmetic operators (+, -, * and /), a space, or something ! else. You can do it with IF-THEN-ELSE-END IF statement; but ! SELECT CASE statement provides a cleaner solution.

!

! For character input, you could use the quote characters like ! 'G'

! Or, just type the character. In this case, the first ! character you type will be read.

!

---PROGRAM CharacterTesting IMPLICIT NONE

CHARACTER(LEN=1) :: Input

READ(*,*) Input

SELECT CASE (Input)

CASE ('A' : 'Z', 'a' : 'z') ! rule out letters WRITE(*,*) 'A letter is found : "', Input, '"' SELECT CASE (Input) ! a vowel ?

CASE ('A', 'E', 'I', 'O', 'U', 'a', 'e', 'i', 'o','u') WRITE(*,*) 'It is a vowel'

CASE DEFAULT ! it must be a consonant WRITE(*,*) 'It is a consonant'

END SELECT

CASE ('0' : '9') ! a digit

WRITE(*,*) 'A digit is found : "', Input, '"' CASE ('+', '-', '*', '/') ! an operator

WRITE(*,*) 'An operator is found : "', Input, '"' CASE (' ') ! space

(48)

END PROGRAM CharacterTesting

Click here to download this program.

P

ROGRAM

I

NPUT AND

O

UTPUT

How do you input a character to your program? The easiest way is using something like 'Y', "g" and '-'. That is, use single or double quotes.

 If the input character is s, the program should report it is a consonant.

A letter is found : "s" It is a consonant

 If the input character is U, the program should report it is a vowel.

A letter is found : "U" It is a vowel

 If the input character is 8, the program should report it is a digit.

A digit is found : "8"

 If the input character is +, the program should report it is an operator.

An operator is found : "+"

 If the input character is a space, the program should report it is a space.

A space is found : " "

 If the input character is none of the above, say &, the program should report it is something else.

Something else found : "&"

D

ISCUSSION

Referensi

Dokumen terkait

Kayong Utara akan segera menindaklanjutinya dengan melakukan Lelang Ulang dan menayangkan kembali pengumuman tersebut melalui website: lpse.kayongutarakab.go.id. (Dua Milyar Dua

(b) Photoactivation of microinjected caged polypeptides at specific cellular locations can be used to investigate the function and kinetics of specific proteins in processes that

Oleh karena jalur yang digunakan bergantung pada paket per paket, maka jika terjadi kemacetan di jalur satu maka paket dapat disalurkan ke jalur lain.. UDP (User

Kebutuhan perawatan ortodonsi berdasarkan index of orthodontic treatment need pada siswa kelas II di SMP Negerei 2 Bitung. Hariyanti SR, Triwardhani A, Rusdiana

Dalam video informasi pelayanan donor darah, konsep yang akan diangkat adalah tentang pelayanan donor darah, yang disampaikan terstruktur sehingga jelas dan menarik

Dalam pasal yang sama ayat (3), Home Industri Pengolahan Ikan Asin Ngabean Makmur Kendal, diperbolehkan untuk membuang limbah ke media lingkungan dengan syarat memenuhi baku

Dengan melihat hasil uji signifikan Variabel Independent terhadap Analisis Beberapa Faktor Yang Mempengaruhi Penyaluran Kredit Pada Bank Umum Di Jawa Timur (Y), maka dapat

Disajikan gambar penampang melintang salah satu organ pada tumbuhan, siswa dapat menjelaskan fungsi bagian yang ditunjuk.