Você está na página 1de 241

Fortran 90 Tutorial

Fortran 90 Tutorial
Dr. C.-K. Shene

Associate Professor
Department of Computer Science
Michigan Technological University

© 1997 C.-K. Shene

You are visitor since July 1, 1998.


Last update: August 20, 1998.

Select the topics you wish to review:

Introduction and Basic Fortran


Selective Execution (IF-THEN-ELSE and SELECT CASE)
Repetitive Execution (DO Loops)
Functions and Modules
Subroutines
One-Dimensional Arrays
Multi-Dimensional Arrays
Formated Input and Output
Please send comments and suggestions to shene@mtu.edu

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/fortran.html8/5/2006 8:01:06 PM
Introduction and Basic Fortran

Introduction and Basic Fortran

Select the topics you wish to review:

Introduction
Program Structure
Comments
Continuation Lines
Basic Fortran
Alphabets
Constants
Identifiers
Variables and Their Types
Variable Declarations
Assigning a Constant a Name - PARAMETER attribute
Initializing Variables
Arithmetic Operators
Simple Mode Arithmetic Expressions
Mixed Mode Arithmetic Expressions
The Assignment Statement
Intrinsic Functions
List-Directed Input: The READ Statement
List-Directed Output: The WRITE Statement
Programming Examples:
Three Programming Traps
Computing Means
Quadratic Equation Solver
The Length of a Parabola Segment
Projectile motion (intrinsic functions)
Character Operator and Substrings (Optional)
Download my course overheads

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/intro.html8/5/2006 8:01:34 PM
Program structure

Program Structure

Your program should have the following form:

PROGRAM program-name
IMPLICIT NONE
[specification part]
[execution part]
[subprogram part]
END PROGRAM program-name

Here are some addition notes:

● Contents in [ ] are optional.


● Keyword IMPLICIT NONE must present.
● A program starts with the keyword PROGRAM,
❍ followed by a program name,

❍ followed by the IMPLICIT NONE statement,

❍ followed my some specification statements,

❍ followed by the execution part,

❍ followed by a set of internal subprograms,

❍ followed by the keywords END PROGRAM and the program name.

● For improving readability, your program should add comment lines.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap01/struct.html8/5/2006 8:01:48 PM
Fortran identifiers

Fortran Identifiers

A Fortran identifier must satisfy the following rules:

● It has no more than 31 characters


● The first character must be a letter,
● The remaining characters, if any, may be letters, digits, or underscores,
● Fortran identifiers are case insensitive. That is, Smith, smith, sMiTh, SMiTH, smitH are all identical identifiers.
● Correct Examples:
❍ MTU, MI, John, Count

❍ I, X

❍ I1025, a1b2C3, X9900g

❍ R2_D2, R2D2_, A__

● Incorrect Examples:
❍ M.T.U.: only letters, digits, and underscores can be used

❍ R2-D2: same as above

❍ 6feet: the first character must be a letter

❍ _System: same as above

● Use meaningful names


❍ Good names: Total, Rate, length

❍ Not so good names: ThisIsALongFORTRANname, X321, A_B_012cm, OPQ

● Fortran has many keywords such as INTEGER, REAL, PARAMETER, PROGRAM, END, IF, THEN,
ELSE, DO, just name a few; however, Fortran does not have any reserved words. More precisely, a
programmer can use these keywords as identifiers. Therefore, END, PROGRAM, DO are perfectly legal
Fortran identifiers. However, this is definitely not a good practice.

Except for strings, Fortran 90 is not case sensitive. Therefore, identifier Name is identical to name, nAmE, NAme,
NamE and namE. Similarly, PROGRAM is identical to program, PROgram, and progRAM. In this course, all
keywords such as PROGRAM, READ, WRITE and END are in upper case and other identifiers use mixed cases.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/id.html8/5/2006 8:01:56 PM
Fortran comments

Fortran Comments

Comments should be used liberally to improve readability. The following are the rules for making comments:

● All characters following an exclamation mark, !, except in a character string, are commentary, and are ignored by the
compiler.

PROGRAM TestComment1
..........
READ(*,*) Year ! read in the value of Year
..........
Year = Year + 1 ! add 1 to Year
..........
END PROGRAM TestComment1

● An entire line may be a comment

! This is a comment line


!
PROGRAM TestComment2
.........
! This is a comment line in the middle of a program
.........
END PROGRAM TestComment2

● A blank line is also interpreted as a comment line.

PROGRAM TestComment3
..........
READ(*,*) Count

! The above blank line is a comment line


WRITE(*,*) Count + 2
END PROGRAM TestComment3

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap01/comment.html8/5/2006 8:02:03 PM
Fortran alphabets

Fortran Alphabets

Fortran only uses the following characters:

● Letters:

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

● Digits:

0 1 2 3 4 5 6 7 8 9

● Special Characters:

space
' " ( ) * + - / : = _
! & $ ; < > % ? , .

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/alphabet.html8/5/2006 8:02:12 PM
Fortran continuation lines

Fortran Continuation Lines

In Fortran, a statement must start on a new line. If a statement is too long to fit on a line, it can be continued with
the following methods:

● If a line is ended with an ampersand, &, it will be continued on the next line.
● Continuation is normally to the first character of the next non-comment line.

A = 174.5 * Year &


+ Count / 100

The above is equivalent to the following

A = 174.5 * Year + Count / 100

Note that &is notpart of the statement.

A = 174.5 * Year &


! this is a comment line
+ Count / 100

The above is equivalent to the following, since the commentis ignored by the compiler:

A = 174.5 * Year + Count / 100

● If the first non-blank character of the continuation line is &, continuation is to the first character after the &:

A = 174.5 + ThisIsALong&
&VariableName * 123.45

is equivalent to

A = 174.5 + ThisIsALongVariableName * 123.45

In this case, there should be no spaces between the last character and the &on the first line. For example,

A = 174.5 + ThisIsALong &


&VariableName * 123.45

is equivalent to

A = 174.5 + ThisIsALong VariableName * 123.45

Note that there are spaces between ThisIsALongand VariableName. In this way, a token (name and number) can
be split over two lines. However, this is not recommended

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap01/continue.html8/5/2006 8:02:34 PM
Fortran Constants

Fortran Constants

Constants or more formally literal constants are the tokens used to denote the value of a particular type. Fortran has five
types of constants: integer, real, complex, logical, and character string.

● Integer Constants: a string of digits with an optional sign:


❍ Correct Examples: 0, -345, 768, +12345

❍ Incorrect Examples:

■ 1,234 : comma is not allowed

■ 12.0: no decimal point

■ --4 and ++3: too many optional signs

■ 5- and 7+: the optional sign must precede the string of digits

● Real Constants: There are two representations, decimal representation and exponential representation.
❍ Decimal Representation: A decimal point must be presented, but no commas are allowed. A real constant

can have an optional sign.


■ Correct Examples: 23.45, .123, 123., -0.12, -.12

■ Incorrect Examples:

■ 12,345.95: no comma is allowed

■ 75: real constant must have a decimal point

■ 123.5-: the optional sign must precede the number

■ $12.34: cannot use dollar sign $

❍ Exponential Representation: It consists of an integer or a real number in decimal representation (the

mantissa or fractional part), followed by the letter E or e, followed by an integer (the exponent).
■ Correct Examples

■ 12.3456E2 or 12.3456e2: this is equal to 1234.56

■ -3.14E1 or -3.14e1: this is equal to -31.4

■ -1.2E-3 or -1.2e-3: this is equal to -0.0012

■ 12E3 or 12e3: this is equal to 12000.0

■ 0E0 or 0e0: this is equal to 0.0

■ Incorrect Examples

■ 12.34E1.2: the exponential part must be an integer constant

■ 12.34-5: there is no exponential sign E or e

● Complex: Will not be covered in this course


● Logical: See Chapter 3
● Character String: Character constants must be enclosed between double quotes or apostrophes (single quotes).
The content of a string consists of all characters, spaces included, between the single or quote quotes, while the
length of the string is the number of characters of its content. The content of a string can be zero and in this case it is
an empty string
❍ Correct Examples:

■ 'John' and "John": content = John and length = 4

■ ' ' and " ": content = a single space and length = 1

■ 'John Dow #2' and "John Dow #2": content = John Dow #2 and length = 11

■ '' and "": content = nothing and length = 0 (empty string)

❍ Incorrect Examples:

■ 'you and me: the closing apostrophe is missing

■ Hello, world': the opening apostrophe is missing

■ 'Hi" and "Hi': the opening and closing quotes do not match.

If single quote is used in a string, then double quotes should be used to enclose the string:

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/constant.html (1 of 2)8/5/2006 8:02:42 PM


Fortran Constants

"Lori's apple"

This string has content Lori's apple and length 12. Alternatively, you can write the single quote twice as follows:

'Lori''s apple'

The compiler will treat a pair of single quotes in the content of a string as one. Thus, the content of the above string
is still Lori's apple.
❍ Correct Examples:

■ 'What''s this?': content = What's this? and length = 11

■ '''''': content = '' and length = 2

❍ Incorrect Examples:

■ 'Tech's seminar': the single quote between h and s should be written twice.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/constant.html (2 of 2)8/5/2006 8:02:42 PM


Fortran Variables and Their Types

Fortran Variables and Their Types

A Fortran variable can be considered as a box that is capable of holding a single value of certain type. Thus, a variable has
a name, the variable name and a type. The way of choosing a name for a variable must fulfill the rules of composing a
Fortran identifier. The type of a variable can be one of the following:

● INTEGER: the variable is capable of holding an integer


● REAL: the variable is capable of holding a real number
● COMPLEX: the variable is capable of holding a complex number
● LOGICAL: the variable is capable of holding a logical value (i.e., true or false)
● CHARACTER: the variable is capable of holding a character string of certain length

Click here to learn the forms of these values.


Click here to learn more about declaring variables.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/var-type.html8/5/2006 8:02:49 PM
Fortran Variable Declarations

Fortran Variable Declarations

Declaring the type of a Fortran variable is done with type statements. It has the following form:

type-specifier :: list

where the type-specifier is one of the following and list is a list of variable names separated with commas:

● INTEGER : the variables in list can hold integers


● REAL: the variables in list can hold real numbers
● COMPLEX: the variables in list can hold complex numbers
● LOGICAL: the variables in list can hold logical values (i.e., true or false)
● CHARACTER: the variables in list can hold character strings

Types INTEGER and REAL are easy. The following are examples:

● Variables ZIP, Mean and Total are of type INTEGER:

INTEGER :: ZIP, Mean, Total

● Variables Average, error, sum and ZAP are of type REAL:

REAL :: Average, error, sum, ZAP

Type CHARACTER is more involved. Since a string has a length attribute, a length value must be attached to character
variable declarations. There are two ways to do this:

● Use CHARACTER(LEN=i) to declare character variables of length i. For examples,


❍ Name and Street are character variables that can hold a string of no more than 15 characters:

CHARACTER(LEN=15) :: Name, Street

❍ FirstName, LastName and OtherName are character variables that can hold a string of no more than 20
characters:

CHARACTER(LEN=20) :: FirstName, LastName, OtehrName

● Use CHARACTER(i) to declare character variables of length i. That is, there is no LEN= in the parenthesis. For
examples,
❍ Name and Street are character variables that can hold a string of no more than 15 characters:

CHARACTER(15) :: Name, Street

❍ FirstName, LastName and OtherName are character variables that can hold a string of no more than 20
characters:

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/declare.html (1 of 2)8/5/2006 8:02:50 PM


Fortran Variable Declarations

CHARACTER(20) :: FirstName, LastName, OtehrName

● If a variable can only hold a single character, the length part can be removed. The following three declarations are all
equivalent:

CHARACTER(LEN=1) :: letter, digit


CHARACTER(1) :: letter, digit
CHARACTER :: letter, digit

Here, variables letterand digitcan only hold no more than one character.

● If you want to declare character variables of different length with a single statement, you can attach a length
specification, *i, to the right of a variable. In this case, the corresponding variable will have the indicated length and
all other variables are not affected.

CHARACTER(LEN=10) :: City, Nation*20, BOX, bug*1

Here, variables Cityand BOXcan hold a string of no more than 10 characters, Nationcan hold a string of no more
than 20 characters, and bugcan hold only one character.

● There is one more way of specifying the length of a character variable. If the length value is replaced with a asterisk
*, it means the lengths of the declared variables are determined elsewhere. In general, this type of declarations is used
in subprogram arguments or in PARAMETER and is refereed to as assumed length specifier.

CHARACTER(LEN=*) :: Title, Position

Here, the actual lengths of variables Titleand Positionare unknown and will be determined elsewhere.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/declare.html (2 of 2)8/5/2006 8:02:50 PM


The PARAMETER Attribute

The PARAMETER Attribute

In many places, one just wants to assign a name to a particular value. For example, keep typing 3.1415926 is tedious. In this
case, one could assign a name, say PI, to 3.1415926 so that one could use PI rather than 3.1415926. To assign a name to a
value, one should do the following:

● Add PARAMETER in front of the double colon (::) and use a comma to separate the type name (i.e., REAL) and
the word PARAMETER
● Following each name, one should add an equal sign (=) followed by an expression. The value of this expression is
then assigned the indicated name.
● After assigning a name to a value, one can use the name, rather than its value throughout the program. The compiler
would convert that name to its corresponding value.
● It is important to note that the name assigned to a value is simply an alias of the value. Therefore, that name is not a
variable.
● After assigning a name to a value, that name can be used in a program, even in subsequent type statements.

Examples:

● In the example blow, Limit is a name for the integer value 30, while Max_Count is a name for the integer value
100:

INTEGER, PARAMETER :: Limit = 30, Max_Count = 100

● In the example below, E is a name for the real value 2.71828, while PI is a name for the real value 3.141592:

REAL, PARAMETER :: E = 2.71828, PI = 3.141592

● In the example below, Total and Count are names for 10 and 5, respectively. The name, Sum, is defined to be the
product of the values of Total and Count and hence Sum is the name for the value 50(=10*5).

INTEGER, PARAMETER :: Total = 10, Count = 5, Sum = Total*Count

● In the example below, Name is a name for the string 'John' and State is a name for the string "Utah"

CHARACTER(LEN=4), PARAMETER :: Name = 'John', State = "Utah"

It is importantto know when assigning a name to a string:


❍ If the string is longer, truncation to the right will happen. In the following case, since the length of the string

"Smith" is 5 while the length of Name is 4, the string is truncated to the right and the content of Name is
"Smit"

CHARACTER(LEN=4), PARAMETER :: Name = 'Smith'

❍ If the string is shorter, spaces will be added to the right. Since the string "LA" is of length 2 while the name

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/param.html (1 of 2)8/5/2006 8:02:52 PM


The PARAMETER Attribute

City is of length 4, two spaces will be padded to the right and the content of City becomes "LA "

CHARACTER(LEN=4), PARAMETER :: City = "LA"

● This is where the assumed length specifier comes in. That is, Fortran allows the length of character name to be
determined by the length of s string. In the example below, names Name and City are declared to have assumed
length. Since the lengths of 'John' and "LA" are 4 and 2, the length of the names Name and City are 4 and 2,
respectively.

CHARACTER(LEN=*), PARAMETER :: Name = 'John', City = "LA"

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/param.html (2 of 2)8/5/2006 8:02:52 PM


Variables Initialization

Variables Initialization

A variable can be considered as a box that can hold a single value. However, initially the content of a variable (or a box) is
empty. Therefore, before one can use a variable, it must receive a value. Do not assume the compiler or computer will
put some value, say 0, into a variable. There are at least three ways to put a value into a variable:

● initializing it when the program is run


● using an assignment statement
● reading a value from keyboard or other device with a READ statement.

The way of initializing a variable is very similar to the use of PARAMETER attribute. More precisely, do the following to
initial a variable with the value of an expression:

● add an equal sign (=) to the right of a variable name


● to the right of the equal sign, write an expression. It is important to note that all names in the expression must
constants or names of constants.

Initializing a variable is only done exactly once when the computer loads your program into memory for execution. That is,
all initializations are done before the program starts its execution. Using un-initialized variables may cause unexpected
result.

Examples:

● The following example initializes variables Offset to 0.1, Length to 10.0, and tolerance to 1.E-7.

REAL :: Offset = 0.1, Length = 10.0, tolerance = 1.E-7

● The following example initializes variables State1 to "MI", State2 to "MN", and State3 to "MD".

CHARACTER(LEN=2) :: State1 = "MI", State2 = "MN", State3 = "MD"

● The following example first defines three named integer constants with PARAMETER and uses these values to
initialize two integer variables. Thus, variables Pay and Received are initialized to have values 4350 (=10*435) and
8 (3+5), respectively.

INTEGER, PARAMETER :: Quantity = 10, Amount = 435, Period = 3


INTEGER :: Pay = Quantity*Amount, Received = Period+5

● The following example contains a mistake. While the compiler is processing the initialization value for variable
Received, the value of Period is unknown, although it will be defined on the next line.

INTEGER, PARAMETER :: Quantity = 10, Amount = 435


INTEGER :: Pay = Quantity*Amount, Received = Period+5
INTEGER, PARAMETER :: Period = 3

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/var-init.html8/5/2006 8:02:53 PM
Arithmetic Operators

Arithmetic Operators

Fortran has four types of operators: arithmetic, relational, logical, and character. The following is a table of these
operators, including their priority and associativity.

Type Operator Associativity


** right to left
Arithmetic * / left to right
+ - left to right
/
Relational < <= > >= == none
=
.NOT. right to left
.AND. left to right
Logical
.OR. left to right
.EQV. .NEQV. left to right

Some Useful Notes:

● In the table, the operator on the top-most row (**) has the highest priority (i.e., it will be evaluated first) while the
operators on the bottom-most row (i.e., .EQV. and .NEQV.) have the lowest priority. The operators on the same row
have the same priority. In this case, the order of evaluation is based on their associativity law.
● In addition to addition +, subtraction -, multiplication * and division /, Fortran has an exponential operator **. Thus,
raising X to the Y-th power is written as X**Y. For example, the square of 5 is 5**2, and the square root of 5 is
5**0.5. The exponential operator has the highest priority.
● Operators + and - can also be used as unary operators, meaning that they only need one operand. For example, -A
and +X. The former means change the sign of A, while the latter is equivalent to X.
● Unary operators + and - have the same priority as their binary counterparts (i.e., addition + and subtraction -). As a
result, since ** is higher than the negative sign -, -3**2 is equivalent to -(3**2), which is -9.
● For arithmetic operators, the exponential operator ** is evaluated from right to left. Thus, A**B**C is equal to A**
(B**C) rather than (A**B)**C

Click here for single mode arithmetic expressions


Click here for mixed mode arithmetic expressions

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/operator.html8/5/2006 8:02:55 PM
Single Mode Arithmetic Expressions

Single Mode Arithmetic Expressions

An arithmetic expression is an expression using additions +, subtractions -, multiplications *, divisions /, and exponentials
**. A single mode arithmetic expression is an expression all of whose operands are of the same type (i.e. INTEGER,
REAL or COMPLEX). However, only INTEGER and REAL will be covered in this note. Therefore, those values or
variables in a single mode arithmetic expression are all integers or real numbers.

In single mode arithmetic expressions, the result of an operation is identical to that of the operands. The following is a table
showing this fact. The empty entries will be discussed in mixed mode arithmetic expressions.

Operator INTEGER REAL


INTEGER INTEGER mixed mode
mixed
REAL REAL
mode

Simple Examples:

● 1 + 3 is 4
● 1.23 - 0.45 is 0.78
● 3 * 8 is 24
● 6.5/1.25 is 5.2
● 8.4/4.2 is 2.0 rather than 2, since the result must be of REAL type.
● -5**2 is -25
● 12/4 is 3
● 13/4 is 3 rather than 3.25. Since 13/4 is a single mode arithmetic expression and since all of its operands are of
INTEGER type, the result must also be of INTEGER type. The computer will truncate the mathematical result
(3.25) making it an integer. Therefore, the result is 3.
● 3/5 is 0 rather than 0.6.

Rules for Evaluating Expressions

The following are rules of evaluating a more complicated single mode arithmetic expression:

● Expressions are always evaluated from left to right


● If an operator is encountered in the process of evaluation, its priority is compared with that of the next one:
❍ if the next one is lower, evaluate the current operator with its operands

3 * 5 - 4

In the above expression, in the left to right scan, operator *is encountered first. Since the the operator -is
lower, 3 * 5is evaluated first transforming the given expression to 15 - 4. Hence, the result is 11.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/exp-1.html (1 of 3)8/5/2006 8:02:56 PM


Single Mode Arithmetic Expressions

❍ if the next one is equal to the current, the associativity rules are used to determine which one should be
evaluated. For example, if both the current and the next operators are *, then 3 * 8 * 6 will be evaluated as (3
* 8) * 6. On the other hand, if the operator is **, A ** B ** C will be evaluated as A ** (B ** C).
❍ if the next one is higher than the current, the scan should continue with the next operator. For example,
consider the following expression:

4 + 5 * 7 ** 3

if the current operator is +, since the next operator *has higher priority, the scan continues to *. Once the scan
arrives at *, since the next operator **is higher, 7 ** 3is evaluated first, transforming the given expression to

4 + 5 * 343

Then, the new expression is scan again. The next operator to be evaluated is *, followed by +. Thus, the
original expression is evaluated as 4 + (5 * (7 ** 3)).

More Complicated Examples:

In the following examples, brackets are used to indicated the order of evaluation.

● The result is 4 rather than 4.444444 since the operands are all integers.

2 * 4 * 5 / 3 ** 2
--> [2 * 4] * 5 / 3 ** 2
--> 8 * 5 / 3 ** 2
--> [8 * 5] / 3 ** 2
--> 40 / 3 ** 2
--> 40 / [3 ** 2]
--> 40 / 9
--> 4

● As in mathematics, subexpressions in parenthesis must be evaluated first.

100 + (1 + 250 / 100) ** 3


--> 100 + (1 + [250 / 100]) ** 3
--> 100 + (1 + 2) ** 3
--> 100 + ([1 + 2]) ** 3
--> 100 + 3 ** 3
--> 100 + [3 ** 3]
--> 100 + 27
--> 127

● In the following example, x**0.25 is equivalent to computing the fourth root of x. In general, taking the k-th root of
x is equivalent to x**(1.0/k) in Fortran, where k is a real number.

1.0 + 2.0 * 3.0 / ( 6.0*6.0 + 5.0*44.0) ** 0.25


--> 1.0 + [2.0 * 3.0] / (6.0*6.0 + 5.0*44.0) ** 0.25

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/exp-1.html (2 of 3)8/5/2006 8:02:56 PM


Single Mode Arithmetic Expressions

--> 1.0 + 6.0 / (6.0*6.0 + 5.0*55.0) ** 0.25


--> 1.0 + 6.0 / ([6.0*6.0] + 5.0*44.0) ** 0.25
--> 1.0 + 6.0 / (36.0 + 5.0*44.0) ** 0.25
--> 1.0 + 6.0 / (36.0 + [5.0*44.0]) ** 0.25
--> 1.0 + 6.0 / (36.0 + 220.0) ** 0.25
--> 1.0 + 6.0 / ([36.0 + 220.0]) ** 0.25
--> 1.0 + 6.0 / 256.0 ** 0.25
--> 1.0 + 6.0 / [256.0 ** 0.25]
--> 1.0 + 6.0 / 4.0
--> 1.0 + [6.0 / 4.0]
--> 1.0 + 1.5
--> 2.5

Click here to continue with mixed mode arithmetic expressions.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/exp-1.html (3 of 3)8/5/2006 8:02:56 PM


Mixed Mode Arithmetic Expressions

Mixed Mode Arithmetic Expressions

If operands in an expression contains both INTEGER and REAL constants or variables, this is a mixed mode arithmetic
expression.

In mixed mode arithmetic expressions, INTEGER operands are always converted to REAL before carrying out any
computations. As a result, the result of a mixed mode expression is of REAL type. The following is a table showing this
fact.

Operator INTEGER REAL


INTEGER INTEGER REAL
REAL REAL REAL

The rules for evaluating mixed mode arithmetic expressions are simple:

● Use the rules for evaluating single mode arithmetic expressions for scanning.
● After locating an operator for evaluation, do the following:
❍ if the operands of this operator are of the same type, compute the result of this operator.

❍ otherwise, one of the operand is an integer while the other is a real number. In this case, convert the integer to

a real (i.e., adding .0 at the end of the integer operand) and compute the result. Note that since both operands
are real numbers, the result is a real number.
● There is an exception, though. In a**n, where a is a real and n is a positive integer, the result is computed by
multiplying n copies of a. For example, 3.5**3 is computed as 3.5*3.5*3.5

Simple Examples:

● 1 + 2.5 is 2.5
● 1/2.0 is 0.5
● 2.0/8 is 0.25
● -3**2.0 is -9.0
● 4.0**(1/2) is first converted to 4.0**0 since 1/2 is a single mode expression whose result is 0. Then, 4.0**0 is 1.0

An Important Note:

In expression a**b where a is REAL, the result is undefined if the value of a is negative. For example, -
4.0**2 is defined with -16.0 as its result, while (-4.0)**2 is undefined.

More Complicated Examples:

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/exp-2.html (1 of 2)8/5/2006 8:02:58 PM


Mixed Mode Arithmetic Expressions

In the following, brackets will be used to indicated the order of evaluation and braces will be used to indicated an integer-to-
real conversion.

● Note that 6.0 ** 2 is not converted to 6.0 ** 2.0. Instead, it is computed as 6.0 * 6.0.

5 * (11.0 - 5) ** 2 / 4 + 9
--> 5 * (11.0 - {5}) ** 2 / 4 + 9
--> 5 * (11.0 - 5.0) ** 2 / 4 + 9
--> 5 * ([11.0 - 5.0]) ** 2 / 4 + 9
--> 5 * 6.0 ** 2 / 4 + 9
--> 5 * [6.0 ** 2] / 4 + 9
--> 5 * 36.0 / 4 + 9
--> {5} * 36.0 / 4 + 9
--> 5.0 * 36.0 / 4 + 9
--> [5.0 * 36.0] / 4 + 9
--> 180.0 / 4 + 9
--> 180.0 / {4} + 9
--> 180.0 / 4.0 + 9
--> [180.0 / 4.0] + 9
--> 45.0 + 9
--> 45.0 + {9}
--> 45.0 + 9.0
--> 54.0

● In the following, 25.0 ** 1 is not converted, and 1 / 3 is zero.

25.0 ** 1 / 2 * 3.5 ** (1 / 3)
--> [25.0 ** 1] / 2 * 3.5 ** (1 / 3)
--> 25.0 / 2 * 3.5 ** (1 / 3)
--> 25.0 / {2} * 3.5 ** (1 / 3)
--> 25.0 / 2.0 * 3.5 ** (1 / 3)
--> 12.5 * 3.5 ** (1 / 3)
--> 12.5 * 3.5 ** ([1 / 3])
--> 12.5 * 3.5 ** 0
--> 12.5 * [3.5 ** 0]
--> 12.5 * 1.0
--> 12.5

Click here to continue with single mode arithmetic expressions.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/exp-2.html (2 of 2)8/5/2006 8:02:58 PM


The Assignment Statement

The Assignment Statement

The assignment statement has the following form:

variable = expression

Its purpose is saving the result of the expression to the right of the assignment operator to the variable on the left. Here are
some rules:

● The expression is evaluated first with the rules discussed in the single mode or the mixed mode expressions pages.
● If the type of the expression is identical to that of the variable, the result is saved in the variable.
● Otherwise, the result is converted to the type of the variable and saved there.
❍ If the type of the variable is INTEGER while the type of the result is REAL, the fractional part, including

the decimal point, is removed making it an integer result.


❍ If the type of the variable is REAL while the type of the result is INTEGER, then a decimal point is

appended to the integer making it a real number.


● Once the variable receives a new value, the original one disappears and is no more available.
● CHARACTER assignment follows the rules stated in the discussion of the PARAMETER attribute.

Examples:

● The program segment below declares three INTEGER variables. The first assignment statement saves an integer
value to variable Unit. The second saves a real number 100.99 into variable Amount. However, since Amount is an
INTEGER variable, the real value 100.99 is converted to an integer, 100, and saved into Amount. Thus, after the
second assignment completes, variable Amount holds 100. The third assignment computes the single mode
expression, yielding a result 500 = 5*100. Thus, variable Total receives 500.

INTEGER :: Total, Amount, Unit

Unit = 5
Amount = 100.99
Total = Unit * Amount

● In the following, PI is a PARAMETER and is an alias of 3.1415926. The first assignment statement puts integer
value 5 into integer variable Radius. The expression in the second assignment is first evaluated, yielding a result
78.539815, which is then saved into REAL variable Area.

REAL, PARAMETER :: PI = 3.1415926


REAL :: Area
INTEGER :: Radius

Radius = 5
Area = (Radius ** 2) * PI

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/assign.html (1 of 3)8/5/2006 8:03:06 PM


The Assignment Statement

● In the following, Counter is an INTEGER variable initialized to zero.

The meaning of the first assignment is computing the sum of the value in Counter and 1, and saves it back to
Counter. Since Counter's current value is zero, Counter + 1 is 1+0 = 1 and hence 1 is saved into Counter.
Therefore, the new value of Counter becomes 1 and its original value 0 disappears.

The second assignment statement computes the sum of Counter's current value and 3, and saves the result back to
Counter. Thus, the new value of Counter is 1+3=4.

INTEGER :: Counter = 0

Counter = Counter + 1
Counter = Counter + 3

● The following swaps the values in A and B, with the help of C. That is, after completing the following three
assignment statements, A and B have 5 and 3, respectively.

Initially, A and B are initialized to 3 and 5, respectively, while C is uninitialized. The first assignment statement puts
A's value into C, making A=3, B=5 and C=3.

The second assignment statements puts B's value into A. This destroys A's original value 3. After this, A = 5, B = 5
and C = 3.

The third assignment statement puts C's value into B. This makes A=5, B=3 and C=3. Therefore, the values in A and
B are exchanged.

INTEGER :: A = 3, B = 5, C

C = A
A = B
B = C

The following is another possible solution; but, it uses one more variable.

INTEGER :: A = 3, B = 5, C, D

C = A
D = B
A = D
B = C

An Important Note:

A name declared with the PARAMETER attribute is an alias of a value and is not a variable.
Therefore, it cannot be used on the left-hand side of =, although it can be used on the right-hand side.
The following is wrong!

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/assign.html (2 of 3)8/5/2006 8:03:06 PM


The Assignment Statement

INTEGER, PARAMETER :: InchToCM = 2.54, factor = 123.45


INTEGER :: X = 15

InchToCM = factor * X

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/assign.html (3 of 3)8/5/2006 8:03:06 PM


Fortran Intrinsic Functions

Fortran Intrinsic Functions

Fortran provides many commonly used functions, called intrinsic functions. To use a Fortran function, one needs to
understand the following items:

● the name and meaning of the function such as ABS() and SQRT()
● the number of arguments
● the range of the argument
● the types of the arguments
● the type of the return value or the function value

For example, function SQRT() accepts a REAL argument whose value must be non-negative and computes and returns the
square root of the argument. Therefore, SQRT(25.0) returns the square root of 25.0 and SQRT(-1.0) would cause an error
since the argument is negative.

● Mathematical functions:

Return
Function Meaning Arg. Type
Type
INTEGER INTEGER
ABS(x) absolute value of x
REAL REAL
SQRT(x) square root of x REAL REAL
SIN(x) sine of x radian REAL REAL
COS(x) cosine of x radian REAL REAL
TAN(x) tangent of x radian REAL REAL
ASIN(x) arc sine of x REAL REAL
ACOS
arc cosine of x REAL REAL
(x)
ATAN
arc tangent of x REAL REAL
(x)
EXP(x) exp(x) REAL REAL
natural logarithm of
LOG(x) REAL REAL
x

Note that all trigonometric functions use radian rather than degree for measuring angles. For function ATAN(x), x
must be in (-PI/2, PI/2). For ASIN(x) and ACOS(x), x must be in [-1,1].

● Conversion functions:

Return
Function Meaning Arg. Type
Type

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/funct.html (1 of 3)8/5/2006 8:03:18 PM


Fortran Intrinsic Functions

INT(x) integer part x REAL INTEGER


NINT(x) nearest integer to x REAL INTEGER
greatest integer less than or equal to
FLOOR(x) REAL INTEGER
x
FRACTION
the fractional part of x REAL REAL
(x)
REAL(x) convert x to REAL INTEGER REAL

● Other functions:

Return
Function Meaning Arg. Type
Type
MAX(x1, x2, ..., maximum of x1, x2, ... INTEGER INTEGER
xn) xn REAL REAL
INTEGER INTEGER
MIN(x1, x2, ..., xn) minimum of x1, x2, ... xn
REAL REAL
remainder x - INT(x/y) INTEGER INTEGER
MOD(x,y)
*y REAL REAL

Functions in an Expression:

● Functions have higher priority than any arithmetic operators.


● All arguments of a function can be expressions. These expressions are evaluated first and passed to the function for
computing the function value.
● The returned function value is treated as a value in the expression.

An Example:

The example below has three initialized variables A, B and C. The result is computed and saved into uninitialized variable
R.

REAL :: A = 1.0, B = -5.0, C = 6.0


REAL :: R

R = (-B + SQRT(B*B - 4.0*A*C))/(2.0*A)

The following uses brackets to indicated the order of evaluation:

(-B + SQRT(B*B - 4.0*A*C))/(2.0*A)


--> ([-B] + SQRT(B*B - 4.0*A*C))/(2.0*A)

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/funct.html (2 of 3)8/5/2006 8:03:18 PM


Fortran Intrinsic Functions

--> (5.0 + SQRT(B*B - 4.0*A*C))/(2.0*A)


--> (5.0 + SQRT([B*B] - 4.0*A*C))/(2.0*A)
--> (5.0 + SQRT(25.0 - 4.0*A*C))/(2.0*A)
--> (5.0 + SQRT(25.0 - [4.0*A]*C))/(2.0*A)
--> (5.0 + SQRT(25.0 - 4.0*C))/(2.0*A)
--> (5.0 + SQRT(25.0 - [4.0*C))/(2.0*A)
--> (5.0 + SQRT(25.0 - 24.0))/(2.0*A)
--> (5.0 SQRT([25.0 - 24.0]))/(2.0*A)
--> (5.0 + SQRT(1.0))/(2.0*A)
--> (5.0 + 1.0)/(2.0*A)
--> ([5.0 + 1.0])/(2.0*A)
--> 6.0/(2.0*A)
--> 6.0/([2.0*A])
--> 6.0/2.0
--> 3.0

Therefore, R receives 3.0.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/funct.html (3 of 3)8/5/2006 8:03:18 PM


Listed-Directed Input: The READ Statement

Listed-Directed Input: The READ Statement

List-directed input is carried out with the Fortran READ statements. The READ statement can read input values into a set
of variables from the keyboard.

The READ statement has the following forms:

READ(*,*) var1, var2, ..., varn


READ(*,*)

The first form starts with READ(*,*), followed by a list of variable names, separated by commas. The computer will read
values from the keyboard successively and puts the value into the variables. The second form only has READ(*,*), which
has a special meaning.

● The following example reads in four values into variables Factor, N, Multiple and tolerance in this order.

INTEGER :: Factor, N
REAL :: Multiple, tolerance

READ(*,*) Factor, N, Multiple, tolerance

● The following example reads in a string into Title, followed by three real numbers into Height, Length and Area.

CHARACTER(LEN=10) :: Title
REAL :: Height, Length, Area

READ(*,*) Title, Height, Length, Area

Preparing Input Data:

Preparing input data is simple. Here are the rules:

● If a READ statement needs some input values, start a new line that contains the input. Make sure the type of the
input value and the type of the corresponding variable are the same. The input data values must be separated by
space or commas.

For the following READ

CHARACTER(LEN=5) :: Name
REAL :: height, length
INTEGER :: count, MaxLength

READ(*,*) Name, height, count, length, MaxLength

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/read-1.html (1 of 3)8/5/2006 8:03:21 PM


Listed-Directed Input: The READ Statement

The input data may look like the following:

"Smith" 100.0 25 123.579 10000

Note that all input data are on the same line and separated with spaces. After reading in this line, the contents of the
variables are

Name "Smith"
height 100.0
count 25
length 123.579
MaxLength 100000

● Input values can be on several lines. As long as the number of input values and the number of variables in the
corresponding READ agree, the computer will search for the input values. Thus, the following input should produce
the same result. Note that even blank lines are allowed in input.

"Smith" 100.0

25
123.579
10000

● The execution of a READ always starts searching for input values with a new input line.

INTEGER :: I, J, K, L, M, N

READ(*,*) I, J
READ(*,*) K, L, M
READ(*,*) N

If the above READstatements are used to read the following input lines,

100 200
300 400 500
600

then I, J, K, L, Mand Nwill receive 100, 200, 300, 400, 500 and 600, respectively.
● Consequently, if the number of input values is larger than the number of variables in a READ statement, the extra
values will be ignored. Consider the following:

INTEGER :: I, J, K, L, M, N

READ(*,*) I, J, K
READ(*,*) L, M, N

If the input lines are

100 200 300 400

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/read-1.html (2 of 3)8/5/2006 8:03:21 PM


Listed-Directed Input: The READ Statement

500 600 700 800


900

Variables I, Jand Kreceive 100, 200 and 300, respectively. Since the second READstarts with a new line, L, Mand
Nreceive 500, 600 and 700, respectively. 400 on the first input line is lost. The next READwill start reading with the
third line, picking up 900. Hence, 800 is lost.
● A limited type conversion is possible in a READ statement. If the input value is an integer and the corresponding
variable is of REAL type, the input integer will be convert to a real number.

But, if the input value is a real number and the corresponding variable is of INTEGER type, an error will occur.

The length of the input string and the length of the corresponding CHARACTER variable do not have to be equal.
If they are not equal, truncation or padding with spaces will occur as discussed in the PARAMETER attribute page.
● Finally, a READ without a list of variables simply skips a line of input. Consider the following:

INTEGER :: P, Q, R, S

READ(*,*) P, Q
READ(*,*)
READ(*,*) R, S

If the input lines are

100 200 300


400 500 600
700 800 900

The first READreads 100 and 200 into Pand Qand 300 is lost. The second READstarts with a new input line, which
is the second one. It does not read in anything. The third READstarts with the third line and reads 700 and 800 into
Rand S. As a result, the three input values (i.e., 400, 500 and 600) are all lost. The third value on the third line, 900,
is also lost.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/read-1.html (3 of 3)8/5/2006 8:03:21 PM


Listed-Directed Output: The WRITE Statement

Listed-Directed Output: The WRITE Statement

Listed-directed output is carried with the Fortran WRITE statement. The WRITE statement can display the results of a set
of expressions and character strings. In general, WRITE displays the output on the screen.

The WRITE statement has the following forms:

WRITE(*,*) exp1, exp2, ..., expn


WRITE(*,*)

The first form starts with WRITE(*,*), followed by a list of arithmetic expressions or character strings, separated by
commas. The computer will evaluate the arithmetic expressions and displays the results. Note that if a variable does not
contain a value, its displayed result is unpredictable. The second form only has WRITE(*,*), which has a special meaning.

● The following example displays the values of four variables on screen:

INTEGER :: Factor, N
REAL :: Multiple, tolerance

WRITE(*,*) Factor, N, Multiple, tolerance

● The following example displays the string content of Title, followed by the result of (Height + Length) * Area.

CHARACTER(LEN=10) :: Title
REAL :: Height, Length, Area

WRITE(*,*) Title, (Height + Length) * Area

There are some useful rules:

● Each WRITE starts with a new line.


● Consequently, the second form in which the WRITE does not have a list of expressions just displays a blank line.

INTEGER :: Target
REAL :: Angle, Distance
CHARACTER(LEN=*), PARAMETER :: Time = "The time to hit target " &
IS = " is " &
UNIT = " sec."

Target = 10
Angle = 20.0
Distance = 1350.0
WRITE(*,*) 'Angle = ', Angle
WRITE(*,*) 'Distance = ', Distance
WRITE(*,*)
WRITE(*,*) Time, Target, IS, Angle * Distance, UNIT

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/write-1.html (1 of 2)8/5/2006 8:03:22 PM


Listed-Directed Output: The WRITE Statement

This example may produce the following result:

Angle = 20.0
Distance = 1350.0

The time to hit target 10 is 27000sec.

The blank line is generated by the third WRITE.

The above example uses assumed length specifier (i.e., LEN=*) and continuation lines (i.e., symbol &).

● If there are too many results that cannot be fit into a single line, the computer will display remaining results on the
second, the third line and so on.

Output Format:

There is nothing to worry about the output format. The computer will use the best way to display the results. In other
words, integers and real numbers will be displayed as integers and real numbers. But, only the content of a string will be
displayed. The computer will also guarantee that all significant digits will be shown so that one does not have to worry how
many positions should be used for displaying a number. The consequence is that displaying a good-looking table is a
challenge. This will be discussed in FORMAT statement.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/write-1.html (2 of 2)8/5/2006 8:03:22 PM


Programming Example: Three Programming Traps

Programming Example: Three Programming Traps

Problem Statement

The purpose of this program is to show you three common programming traps:

● A**B**C is not equal to (A**B)**C.


● Dividing an integer with another integer always yields an integer result.
● In PARAMETER, assignment statement and READ, strings may be truncated if the length of the variable at the
receiving end is not long enough.

Solution

! ------------------------------------------------------------
! This program illustrates the following points:
! (1) The exponential trap:
! That is, A**B**C is equal to A**(B**C) rather
! than (A**B)**C.
! (2) The integer division trap:
! That is, 4/6 is ZERO in Fortran rather than
! a real number 0.666666
! Function REAL() is used to illustrate the
! differences.
! (3) The string truncation trap:
! What if the length assigned to a CHARACTER
! is shorter than the length of the string you
! expect the identifier to have? The third part
! shows you the effect.
! ------------------------------------------------------------

PROGRAM Fortran_Traps
IMPLICIT NONE

INTEGER, PARAMETER :: A = 2, B = 2, H = 3
INTEGER, PARAMETER :: O = 4, P = 6
CHARACTER(LEN=5), PARAMETER :: M = 'Smith', N = 'TEXAS'
CHARACTER(LEN=4), PARAMETER :: X = 'Smith'
CHARACTER(LEN=6), PARAMETER :: Y = 'TEXAS'

! The exponential trap

WRITE(*,*) "First, the exponential trap:"


WRITE(*,*) A, ' ** ', B, ' ** ', H, ' = ', A**B**H
WRITE(*,*) '( ', A, ' ** ', B, ' ) **', H, ' = ', (A**B)**H

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/traps.html (1 of 3)8/5/2006 8:03:25 PM


Programming Example: Three Programming Traps

WRITE(*,*) A, ' ** ( ', B, ' ** ', H, ' ) = ', A**(B**H)


WRITE(*,*)

! The integer division trap. Intrinsic function REAL() converts


! an integer to a real number

WRITE(*,*) "Second, the integer division trap:"


WRITE(*,*)
WRITE(*,*) O, ' / ', P, ' = ', O/P
WRITE(*,*) 'REAL( ', O, ' ) / ', P, ' = ', REAL(O)/P
WRITE(*,*) O, ' / REAL( ', P, ' ) = ', O/REAL(P)
WRITE(*,*)

! The string truncation trap

WRITE(*,*) "Third, the string truncation trap:"


WRITE(*,*) 'IS ', M, ' STILL IN ', N, '?'
WRITE(*,*) 'IS ', X, ' STILL IN ', Y, '?'

END PROGRAM Fortran_Traps

Click here to download this program.

Program Output

First, the exponential trap:


2 ** 2 ** 3 = 256
( 2 ** 2 ) **3 = 64
2 ** ( 2 ** 3 ) = 256

Second, the integer division trap:

4 / 6 = 0
REAL( 4 ) / 6 = 0.666666687
4 / REAL( 6 ) = 0.666666687

Third, the string truncation trap:


IS Smith STILL IN TEXAS?
IS Smit STILL IN TEXAS ?

Discussion

● All names in this program are aliases of constants.


● Consider the first group. Variables A, B and H are aliases of 2, 2 and 3. The first WRITE computes A**B**H,
which is equivalent to A**(B**H), and the result is 2**(2**3)=256. The second WRITE computes (A**B)**C and
the result is (2**2)**3=64. The third WRITE computes A**(B**H) and the result is 2**(2**3)=256. Thus, it is

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/traps.html (2 of 3)8/5/2006 8:03:25 PM


Programming Example: Three Programming Traps

clear that A**B**H equal to A**(B**H).


● The second group illustrates the problem unique to integer division. Two integer aliases are involved, namely O and
P with values 4 and 6, respectively. The first WRITE displays O/P and the result is 4/6=0 since it is an integer
division. The second WRITE converts O to real with intrinsic function REAL(). Thus, in computing REAL(O)/P,
the expression is REAL(4)/6, which becomes 4.0/6 and then 4.0/6.0. Thus, the result is 0.6666667. The third
WRITE should give the same result.
● Go back to the top of this program. Alias M and N should have no problem since the length of the names and the
length of the strings agree. Since the length of X is 4 and is shorter than the length of string 'Smith', X only receives
the left-most 4 characters. Now take a look at Y. Since the length of Y is longer than the length of string 'TEXAS',
spaces will be appended to the end to fill up to 6 characters. Thus, Y actually becomes 'TEXAS '. The output should
look like the following:

IS Smith STILL IN TEXAS?


IS Smit STILL IN TEXAS ?

On the second line, it is easily seen that the original Smithbecomes Smitand the original TEXASbecomes TEXAS_,
where _indicates a space.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/traps.html (3 of 3)8/5/2006 8:03:25 PM


Programming Example: Computing Means

Programming Example: Computing Means

Problem Statement

Given three real numbers, its arithmetic mean (average), geometric mean and harmonic mean are defined as follows:

Write a program to compute and display the means of three REAL variables initialized with positive real values.

Solution

! -------------------------------------------------------
! Computes arithmetic, geometric and harmonic means
! -------------------------------------------------------

PROGRAM ComputeMeans
IMPLICIT NONE

REAL :: X = 1.0, Y = 2.0, Z = 3.0


REAL :: ArithMean, GeoMean, HarmMean

WRITE(*,*) 'Data items: ', X, Y, Z


WRITE(*,*)

ArithMean = (X + Y + Z)/3.0
GeoMean = (X * Y * Z)**(1.0/3.0)
HarmMean = 3.0/(1.0/X + 1.0/Y + 1.0/Z)

WRITE(*,*) 'Arithmetic mean = ', ArithMean


WRITE(*,*) 'Geometric mean = ', GeoMean
WRITE(*,*) 'Harmonic Mean = ', HarmMean

END PROGRAM ComputeMeans

Click here to download this program.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/means.html (1 of 2)8/5/2006 8:03:28 PM


Programming Example: Computing Means

Program Output

Data items: 1., 2., 3.

Arithmetic mean = 2.
Geometric mean = 1.81712067
Harmonic Mean = 1.63636363

Discussion

● Variables X, Y and Z are initialized in the first REAL statement, while the second declares three variables,
ArithMean, GeoMean and HarmMean, for holding the result.
● The first WRITE statement displays the values of X, Y and Z. The second WRITE generates a blank line.
● In the second assignment statement that computes the geometric mean, the exponent part is 1.0/3.0 instead of 1/3,
since the latter is zero. 1.0/3 and 1.0/3 also work fine. But, you should not use 0.3, since it is not equal to 1/3.

The parenthesis surrounding X * Y * Z cannot be removed; otherwise, the expression X * Y * Z **(1.0/3.0) means
X * Y * (Z **(1.0/3.0)) since ** has a priority higher than that of *.
● The parenthesis in the third assignment cannot be removed either. Why?

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/means.html (2 of 2)8/5/2006 8:03:28 PM


Programming Example: Quadratic Equation Solver

Programming Example: Quadratic Equation Solver

Problem Statement

Given a quadratic equation as follows:

if b*b-4*a*c is non-negative, the roots of the equation can be computed with the following formulae:

Write a program to read in the coefficients a, b and c, and compute and display the roots. You can assume that b*b - 4*a*c
is always non-negative.

Solution

! ---------------------------------------------------
! Solve Ax^2 + Bx + C = 0 given B*B-4*A*C >= 0
! ---------------------------------------------------

PROGRAM QuadraticEquation
IMPLICIT NONE

REAL :: a, b, c
REAL :: d
REAL :: root1, root2

! read in the coefficients a, b and c

WRITE(*,*) 'A, B, C Please : '


READ(*,*) a, b, c

! compute the square root of discriminant d

d = SQRT(b*b - 4.0*a*c)

! solve the equation

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/quad-1.html (1 of 2)8/5/2006 8:03:32 PM


Programming Example: Quadratic Equation Solver

root1 = (-b + d)/(2.0*a) ! first root


root2 = (-b - d)/(2.0*a) ! second root

! display the results

WRITE(*,*)
WRITE(*,*) 'Roots are ', root1, ' and ', root2

END PROGRAM QuadraticEquation

Click here to download this program.

Program Output

A, B, C Please :
1.0 -5.0 3.0

Roots are 4.30277538 and 0.697224379

The input to the above problem consists of three real numbers, 1.0, -5.0 and 3.0, and the computed roots are 4.30277538
and 0.697224379.

Discussion

● The WRITE displays a message like this

A, B, C Please :

After displaying this message, the computer executes READ. Since there is no input value, it will wait until the user
types in three real values and hits the Returnkey. Then, these values are stored in a, band c.
● The first assignment statement computes the square root of the discriminant (i.e., b*b - 4.0*a*c) and stores it into
variable d.
● The roots are computed with the second and third assignments. Note that the parenthesis surrounding 2.0*a cannot
be removed; otherwise, it is equivalent to ((-b + d)/2.0)*a, which is wrong.
● The last two WRITE statements display the roots.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/quad-1.html (2 of 2)8/5/2006 8:03:32 PM


Programming Example: The Length of a Parabola Segment

Programming Example: The Length of a Parabola Segment

Problem Statement

Given base b and height h, the length of a special segment on a parabola can be computed as follows:

Write a program to read in the values of base and height, and use the above formula to compute the length of the parabola
segment. Note that both base and height values must be positive.

Solution

! -----------------------------------------------------------
! Calculate the length of a parabola given height and
base. *
! -----------------------------------------------------------

PROGRAM ParabolaLength
IMPLICIT NONE

REAL :: Height, Base, Length


REAL :: temp, t

WRITE(*,*) 'Height of a parabola : '


READ(*,*) Height

WRITE(*,*) 'Base of a parabola : '


READ(*,*) Base

! ... temp and t are two temporary variables

t = 2.0 * Height
temp = SQRT(t**2 + Base**2)
Length = temp + Base**2/t*LOG((t + temp)/Base)

WRITE(*,*)
WRITE(*,*) 'Height = ', Height
WRITE(*,*) 'Base = ', Base
WRITE(*,*) 'Length = ', Length

END PROGRAM ParabolaLength

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/p-length.html (1 of 2)8/5/2006 8:03:39 PM


Programming Example: The Length of a Parabola Segment

Click here to download this program.

Program Output

Height of a parabola :
100.0

Base of a parabola :
78.5

Height = 100.
Base = 78.5
Length = 266.149445

The input values for Height and Base are 100.0 and 78.5, respectively. The computed length is 266.149445.

Discussion

● The values of base and height will be stored in REAL variables Base and Height, respectively. Length will be used
to store the parabola segment length.
● Since the content in the square root is used twice, it would be more convenient to save the result in a variable. This
value will be stored in temp. Since 2h also appears a few times, variable t is used to store this value. After reading in
Height and Base, 2.0 * Height is computed and stored in t with the first assignment. Then, the second assignment
computes the content in the square root and stores the result into temp.
● The third assignment compute the segment length and stores the result into Length. Note that intrinsic function LOG
() is used.
● The four WRITE statements display the input and the results.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/p-length.html (2 of 2)8/5/2006 8:03:39 PM


Programming Example: Projectile Motion

Programming Example: Projectile Motion

Problem Statement

This program computes the position (x and y coordinates) and the velocity (magnitude and direction) of a projectile, given
t, the time since launch, u, the launch velocity, a, the initial angle of launch (in degree), and g=9.8, the acceleration due to
gravity.

The horizontal and vertical displacements are given by the following formulae:

The horizontal and vertical components of the velocity vector are computed as

and the magnitude of the velocity vector is

Finally, the angle between the ground and the velocity vector is determined by the formula below:

Write a program to read in the launch angle a, the time since launch t, and the launch velocity u, and compute the position,
the velocity and the angle with the ground.

Solution

! --------------------------------------------------------------------
! Given t, the time since launch, u, the launch velocity, a, the
! initial angle of launch (in degree), and g, the acceleration due to
! gravity, this program computes the position (x and y coordinates)
! and the velocity (magnitude and direction) of a projectile.
! --------------------------------------------------------------------

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/projectile.html (1 of 3)8/5/2006 8:03:42 PM


Programming Example: Projectile Motion

PROGRAM Projectile
IMPLICIT NONE

REAL, PARAMETER :: g = 9.8 ! acceleration due to gravity


REAL, PARAMETER :: PI = 3.1415926 ! you knew this. didn't you

REAL :: Angle ! launch angle in degree


REAL :: Time ! time to flight
REAL :: Theta ! direction at time in degree
REAL :: U ! launch velocity
REAL :: V ! resultant velocity
REAL :: Vx ! horizontal velocity
REAL :: Vy ! vertical velocity
REAL :: X ! horizontal displacement
REAL :: Y ! vertical displacement

READ(*,*) Angle, Time, U

Angle = Angle * PI / 180.0 ! convert to radian


X = U * COS(Angle) * Time
Y = U * SIN(Angle) * Time - g*Time*Time / 2.0
Vx = U * COS(Angle)
Vy = U * SIN(Angle) - g * Time
V = SQRT(Vx*Vx + Vy*Vy)
Theta = ATAN(Vy/Vx) * 180.0 / PI

WRITE(*,*) 'Horizontal displacement : ', X


WRITE(*,*) 'Vertical displacement : ', Y
WRITE(*,*) 'Resultant velocity : ', V
WRITE(*,*) 'Direction (in degree) : ', Theta

END PROGRAM Projectile

Click here to download this program.

Program Output

If the input to the program consists of the following three real values:

45.0 6.0 60.0

The program will generate the following output:

Horizontal displacement : 254.558472


Vertical displacement : 78.158432
Resultant velocity : 45.4763107
Direction (in degree) : -21.1030636

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/projectile.html (2 of 3)8/5/2006 8:03:42 PM


Programming Example: Projectile Motion

Discussion

● The program uses Angle for the angle a, Time for t, and U for u. The READ statement reads the input.
● The first assignment statement converts the angle in degree to radian. This is necessary since all intrinsic
trigonometric functions use radian rather than degree.
● Variables X and Y, which are computed in the second and third assignments, hold the displacements.
● The next two assignments compute the components of the velocity vector.
● The velocity itself is computed in the sixth assignment.
● Finally, the angle with ground, Theta, is computed with the last assignment. Note that ithe result is converted back
to degree, since ATAN(x) returns the arc tangent value of x in radian.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/projectile.html (3 of 3)8/5/2006 8:03:42 PM


CHARACTER Operator and Substrings

CHARACTER Operator and Substrings

Concatenation Operator //

Fortran has only one character operator, the concatenation operator //. The concatenation operator cannot be used with
arithmetic operators. Given two strings, s1 and s2 of lengths m and n, respectively, the concatenation of s1 and s2, written
as s1 // s2, contains all characters in string s1, followed by all characters in string s2. Therefore, the length of s1 // s2 is m
+n.

Consider the following statements:

CHARACTER(LEN=4) :: John = "John", Sam = "Sam"


CHARACTER(LEN=6) :: Lori = "Lori", Reagan = "Reagan"
CHARACTER(LEN=10) :: Ans1, Ans2, Ans3, Ans4

Ans1 = John // Lori


Ans2 = Sam // Reagon
Ans3 = Reagon // Sam
Ans4 = Lori // Sam

● Variable Ans1 contains a string "JohnLori**", where * denotes a space. These two spaces come from variable
Lori since its content is "Lori**".
● Variable Ans2 contains a string "Sam Reagan". The space in the string comes from variable Sam since its content
is "Sam*", where, as above, * denotes a space.
● Variable Ans3 contains a string "ReaganSam*".
● Variable Ans4 contains a string "Lori**Sam*".

Substrings

A consecutive part of a string is called a substring. One can append the extent specifier at the end of a CHARACTER
variable to indicate a substring. An extent specifier has a form of

( integer-exp1 : integer-exp2 )

It starts with a (, followed by an integer expression, followed by a colon :, followed by another integer expression, followed
by ). The first integer indicates the first position of the substring, while the second integer indicates the last position of the
substring. Therefore, (3:5) means the substring consists of the third, fourth and fifth characters. If the content of variable
String is "abcdefghijk", then String(3:5) is a string "cde".

If the first integer expression is missing, the value is assumed to be 1. If the second integer expression is missing, the value
is assumed to be the last character of the string. Continue with the example in previous paragraph. String(:4) is string
"abcd". String(2+5:) is string "ghijk".

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/char-opr.html (1 of 4)8/5/2006 8:03:46 PM


CHARACTER Operator and Substrings

As a good programming practice, the value of the first integer expression should be greater than or equal to 1, and the value
of the second integer expression should be less than of equal to the length of the string.

A string variable with an extent specifier can be used on the left-hand side of an assignment. Its meaning is assigning the
string content on the right-hand side into the substring part of the string variable. Let the content of a string variable
LeftHand of length 10 be "1234567890". The following are a few examples:

● LeftHand(3:5) = "abc": the new content of LeftHand is "12abc67890".


● LeftHand(1:6) = "uvwxyz": the new content of LeftHand is "uvwxyz7890".
● LeftHand(:6) = "uvzxyz": the result is identical to the previous example.
● LeftHand(4:) = "lmnopqr": the new content of LeftHand is "123lmnopqr".
● LeftHand(3:8) = "abc": the new content of LeftHand is "12abc***90", where * denotes a space. Note that since
LeftHand(3:8) consists of 6 character positions and "abc" has only three characters, the remaining will be filled
with spaces.
● LeftHand(4:7) = "lmnopq": the new content of LeftHand is "123lmno890". It is due to truncation.

Example

! ----------------------------------------------------------------
! This program uses DATE_AND_TIME() to retrieve the system date
! and the system time. Then, it converts the date and time
! information to a readable format. This program demonstrates
! the use of concatenation operator // and substring
! ----------------------------------------------------------------

PROGRAM DateTime
IMPLICIT NONE

CHARACTER(LEN = 8) :: DateINFO ! ccyymmdd


CHARACTER(LEN = 4) :: Year, Month*2, Day*2

CHARACTER(LEN = 10) :: TimeINFO, PrettyTime*12 ! hhmmss.sss


CHARACTER(LEN = 2) :: Hour, Minute, Second*6

CALL DATE_AND_TIME(DateINFO, TimeINFO)

! decompose DateINFO into year, month and day.


! DateINFO has a form of ccyymmdd, where cc = century, yy = year
! mm = month and dd = day

Year = DateINFO(1:4)
Month = DateINFO(5:6)
Day = DateINFO(7:8)

WRITE(*,*) 'Date information -> ', DateINFO


WRITE(*,*) ' Year -> ', Year
WRITE(*,*) ' Month -> ', Month
WRITE(*,*) ' Day -> ', Day

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/char-opr.html (2 of 4)8/5/2006 8:03:46 PM


CHARACTER Operator and Substrings

! decompose TimeINFO into hour, minute and second.


! TimeINFO has a form of hhmmss.sss, where h = hour, m = minute
! and s = second

Hour = TimeINFO(1:2)
Minute = TimeINFO(3:4)
Second = TimeINFO(5:10)

PrettyTime = Hour // ':' // Minute // ':' // Second

WRITE(*,*)
WRITE(*,*) 'Time Information -> ', TimeINFO
WRITE(*,*) ' Hour -> ', Hour
WRITE(*,*) ' Minite -> ', Minute
WRITE(*,*) ' Second -> ', Second
WRITE(*,*) ' Pretty Time -> ', PrettyTime

! the substring operator can be used on the left-hand side.

PrettyTime = ' '


PrettyTime( :2) = Hour
PrettyTime(3:3) = ':'
PrettyTime(4:5) = Minute
PrettyTime(6:6) = ':'
PrettyTime(7: ) = Second

WRITE(*,*)
WRITE(*,*) ' Pretty Time -> ', PrettyTime

END PROGRAM DateTime

Click here to download this program.

Program Output

Date information -> 19970811


Year -> 1997
Month -> 08
Day -> 11

Time Information -> 010717.620


Hour -> 01
Minite -> 07
Second -> 17.620
Pretty Time -> 01:07:17.620

Pretty Time -> 01:07:17.620

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/char-opr.html (3 of 4)8/5/2006 8:03:46 PM


CHARACTER Operator and Substrings

Discussion

● Subroutine DATE_AND_TIME() returns the date of time and day information into two character arguments. The
first one, DateINFO, must have a length of at least 8. The returned value is in the form of ccyymmdd, where cc
gives the century, yy the year, mm the month, and dd the day. If today is August 11, 1997, the call to this subroutine
returns a string of eight characters "19970811"
● The second argument, TimeINFO, will receive a string of 12 characters with a form of hhmmss.sss, where hh gives
the hour value, mm the minute value, and ss.sss the second value. Thus, if the time this subroutine is called is 1 after
7 minutes and 17.620 seconds, the returned value is "010717.620"

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/char-opr.html (4 of 4)8/5/2006 8:03:46 PM


Selective Execution

Selective Execution

Select 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
Download my course overheads

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/select.html8/5/2006 8:04:19 PM
LOGICAL Type and Variables

LOGICAL Type and Variables

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

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/log-type.html8/5/2006 8:04:23 PM
LOGICAL Input and Output

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.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/log-io.html8/5/2006 8:04:25 PM
Relational Operators

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 different 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 Associativity


** right to left
Arithmetic * / left to right
+ - left to right
/
Relational < <= > >= == none
=

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.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/relational.html (1 of 4)8/5/2006 8:04:29 PM


Relational Operators

Examples

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

Comparing CHARACTER Strings

Characters are encoded. Different standards (e.g. BCD, EBCDIC and ASCII) may have different encoding schemes.
To write a program that can run on all different 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

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/relational.html (2 of 4)8/5/2006 8:04:29 PM


Relational Operators

< 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
different encoding methods may produce different answers. Moreover, do not assume there exists a specific 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 fine.

Here is the method for comparing two strings:

● The comparison always starts at the first 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
❍ both strings have consumed all of their characters, they are equal since all of their corresponding

characters are equal.


❍ otherwise, the shorter string is considered to be the smaller one.

Examples

● Compare "abcdef" and "abcefg"

a b c d e f
= = = <
a b c e f g

The first three characters of both strings are equal. Since 'd' of the first 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 first string is shorter, "01357" < "013579" holds.
● What is the result of "DOG" < "FOX"?

D O G
<
F O X

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/relational.html (3 of 4)8/5/2006 8:04:29 PM


Relational Operators

The first character (i.e., 'D' < 'F') determines the outcome. That is, "DOG" < "FOX" yields .TRUE.

A Special Note

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.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/relational.html (4 of 4)8/5/2006 8:04:29 PM


LOGICAL Operators and Expressions

LOGICAL Operators and Expressions

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 Associativity


** right to left
Arithmetic * / left to right
+ - left to right
/
Relational < <= > >= == none
=
.NOT. right to left
.AND. left to right
Logical
.OR. left to right
.EQV. .NEQV. left to right

Truth Tables

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

Operand Result
. .
.TRUE.
NOT. FALSE.
.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.).

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/logical.html (1 of 5)8/5/2006 8:04:39 PM


LOGICAL Operators and Expressions

The following is the truth table of .AND.:

.AND. .TRUE. .FALSE


.
.TRUE. .TRUE.
FALSE.
. . .
FALSE. FALSE. FALSE.

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

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

.EQV. .TRUE. .FALSE


.
.TRUE. .TRUE.
FALSE.
. .
.TRUE.
FALSE. FALSE.

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

.NEQV. .TRUE. .FALSE

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/logical.html (2 of 5)8/5/2006 8:04:39 PM


LOGICAL Operators and Expressions

.
.TRUE. .TRUE.
FALSE.
. .
.TRUE.
FALSE. FALSE.

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.

Priority

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

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/logical.html (3 of 5)8/5/2006 8:04:39 PM


LOGICAL Operators and Expressions

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

Assignments

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

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/logical.html (4 of 5)8/5/2006 8:04:39 PM


LOGICAL Operators and Expressions

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.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/logical.html (5 of 5)8/5/2006 8:04:39 PM


IF-THEN-ELSE-END IF

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:

● the logical-expression is evaluated, yielding a logical value


● 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 finish executing statements in statements-1 or statements-2, the statement following END IF is executed.

Examples

● The following code first 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

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/if-then-else.html (1 of 2)8/5/2006 8:04:40 PM


IF-THEN-ELSE-END IF

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 finds 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 ', &
b, ' is ', Smaller

A Useful Tip

You may find 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
a <= number
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.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/if-then-else.html (2 of 2)8/5/2006 8:04:40 PM


IF-THEN-END IF

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

Examples

● 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 first 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 finds 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

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/if-then.html (1 of 2)8/5/2006 8:04:42 PM


IF-THEN-END IF

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 satisfied; 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

A Useful Tip

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:

what you want to do when the logical expression is .


logical- TRUE.
expression
nothing is here!!!

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/if-then.html (2 of 2)8/5/2006 8:04:42 PM


Logical IF

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

Examples

● 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 first 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 finds 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

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/if.html (1 of 2)8/5/2006 8:04:44 PM


Logical IF

● In many cases, it is required to do something when certain condition is satisfied; 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.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/if.html (2 of 2)8/5/2006 8:04:44 PM


Programming Example 1: Quadratic Equation Solver

Programming Example 1: Quadratic Equation Solver

Problem Statement

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.

Solution

! ---------------------------------------------------
! 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(*,*)

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/quad-2.html (1 of 3)8/5/2006 8:04:48 PM


Programming Example 1: Quadratic Equation Solver

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

Program Input and Output

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

Discussion

Here is the box trick of this program. Note that information in different parts of the box do not have to be very precise. As

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/quad-2.html (2 of 3)8/5/2006 8:04:48 PM


Programming Example 1: Quadratic Equation Solver

long as it can tell what to do, it would be sufficient.

computes the real


b*b - 4.0*a*c >= roots
0.0
there is no real roots

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/quad-2.html (3 of 3)8/5/2006 8:04:48 PM


Programming Example 2: Final Mark Computation

Programming Example 2: Final Mark Computation

Problem Statement

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

Solution

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

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'

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/mark.html (1 of 2)8/5/2006 8:04:49 PM


Programming Example 2: Final Mark Computation

ELSE
WRITE(*,*) 'Pass Status : FAIL'
END IF

END PROGRAM FinalMark

Click here to download this program.

Program Input and Output

● If the input to class record mark, the mark of the first 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 final 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 first 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.

60.0 45.0 43.0

Class Record Mark : 60.


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

Discussion

● The READ statement reads in values for ClassRecordMark, Mark1 and Mark2.
● The average of papers is computed and stored in Final
● If this final mark is less than or equal to the class record mark, a new final 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 final mark.
● Finally, the IF-THEN-ELSE-END IF determines if the final mark is a pass or a fail.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/mark.html (2 of 2)8/5/2006 8:04:49 PM


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

Programming Example 3: Heron's Formula for Computing


Triangle Area

Problem Statement

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.

Solution

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

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/heron.html (1 of 3)8/5/2006 8:04:54 PM


Programming Example 3: Heron's Formula for Computing 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.

Program Input and Output

● 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.
c = 7.

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 first 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!

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/heron.html (2 of 3)8/5/2006 8:04:54 PM


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

● 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!

Discussion

● 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 first 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 fit 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.

computes s and its area


a, b and c form a
triangle displays an error
message

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/heron.html (3 of 3)8/5/2006 8:04:54 PM


Nested IF-THEN-ELSE-END IF

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

Examples

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

display +
x>
0 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<

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/nest-if.html (1 of 4)8/5/2006 8:04:58 PM


Nested IF-THEN-ELSE-END IF

0 display
0)

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

display +
x> display -
0 x<
0 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.

display -x
x<
0 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 >= 0:

x <= x is in the range of 0 and 1. display 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
0
1

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/nest-if.html (2 of 4)8/5/2006 8:04:58 PM


Nested IF-THEN-ELSE-END IF

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 find 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 is the smallest
a<
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 the
smallest

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

a< the smallest is a


c the smallest is c
a<
b the smallest is
b< b
c
the smallest is c

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/nest-if.html (3 of 4)8/5/2006 8:04:58 PM


Nested IF-THEN-ELSE-END IF

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.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/nest-if.html (4 of 4)8/5/2006 8:04:58 PM


IF-THEN-ELSE IF-END IF

IF-THEN-ELSE IF-END IF

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.

Examples

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

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/else-if.html (1 of 3)8/5/2006 8:04:59 PM


IF-THEN-ELSE IF-END IF

IF (x < 0) THEN
WRITE(*,*) -x
ELSE IF (x <= 1) THEN
WRITE(*,*) x*x
ELSE
WRITE(*,*) 2*x
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 xis less than 50, 'F'is assigned to Grade. If xis greater than or equal to 50, the execution continue with the
first ELSE IFwhere x < 60is tested. If it is .TRUE., 'D'is assigned to Grade. Note that one can reach the test of x <
60simply because the test x < 50is .FALSE.. Therefore, when reaches x < 60, we are sure that x >= 50must hold and
as a result, Gradereceives 'D'if xis 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 first 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

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/else-if.html (2 of 3)8/5/2006 8:04:59 PM


IF-THEN-ELSE IF-END IF

Result = b
ELSE
Result = c
END IF

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/else-if.html (3 of 3)8/5/2006 8:04:59 PM


Quadratic Equation Solver - Again

Quadratic Equation Solver - Again

Problem Statement

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.

Solution

! ---------------------------------------------------
! 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(*,*)

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/quad-3.html (1 of 4)8/5/2006 8:05:03 PM


Quadratic Equation Solver - Again

! 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 IF

END PROGRAM QuadraticEquation

Click here to download this program.

Program Input and Output

● 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

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/quad-3.html (2 of 4)8/5/2006 8:05:03 PM


Quadratic Equation Solver - Again

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

a = 1.
b = 2.
c = 5.

There is no real roots!


Discriminant = -16.

Discussion

Here is the box trick of this program.

computes the real roots


b*b - 4.0*a*c >
0.0 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:

computes the repeated


b*b - 4.0*a*c = root
0.0
no real root

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

computes the real roots


b*b - 4.0*a*c > compute the repeated
0.0 b*b - 4.0*a*c = root
0.0
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

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/quad-3.html (3 of 4)8/5/2006 8:05:03 PM


Quadratic Equation Solver - Again

! 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(*,*)

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

> computes the real roots


b*b - 4.0*a*c ? computes the repeated
=
0.0 root
> no real root

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/quad-3.html (4 of 4)8/5/2006 8:05:03 PM


Quadratic Equation Solver - Revisited

Quadratic Equation Solver - Revisited

Problem Statement

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.

Solution

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

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/quad-5.html (1 of 4)8/5/2006 8:05:07 PM


Quadratic Equation Solver - Revisited

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

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.

Program Input and Output

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

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/quad-5.html (2 of 4)8/5/2006 8:05:07 PM


Quadratic Equation Solver - Revisited

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 coefficients are zero,
any number is a root.

0.0 0.0 0.0

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

Discussion

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.

it could be a linear
a= equation
0
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:

need to know if c is zero


b=
a= 0 the equation is linear b*x
0 +c=0

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/quad-5.html (3 of 4)8/5/2006 8:05:07 PM


Quadratic Equation Solver - Revisited

a quadratic equation

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

every number is a root


c=
b= 0 this equation is not
a= 0 solvable
0
the equation is linear b*x+c=0
a quadratic equation

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

every number is a root


c=
0 this equation is not
b=0
solvable
a= the equation is linear b*x+c=0
0
> computes the real roots
b*b - 4.0*a*c ?
= computes the repeated root
0.0
> no real root

The above program is written based on this logic.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/quad-5.html (4 of 4)8/5/2006 8:05:07 PM


Sort Three Numbers

Sort Three Numbers

Problem Statement

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.

Solution

! -------------------------------------------------------
! 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) 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

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/sort.html (1 of 3)8/5/2006 8:05:10 PM


Sort Three Numbers

Click here to download this program.

Discussion

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< a may be the smallest


b 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 is the smallest, relation between b and c


a< unknown
c
a< c <= a < b here, sorted!!!
b b is the smallest, relation between a and c
b < unknown
c
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:

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


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

The above can be simplified a little if you use LOGICAL operators as discussed in nested IF. Here is the box diagram:

a < b < c here


a < b and a < b<
c c a < b <= c
here

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/sort.html (2 of 3)8/5/2006 8:05:10 PM


Sort Three Numbers

b < a < c here


b < a and b <
a < c b < c <= a
c
here
c < a < b here
a<
c < a and c < b c < b <= a
b
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.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/sort.html (3 of 3)8/5/2006 8:05:10 PM


SELECT CASE Statement

SELECT CASE Statement

Fortran has one more selective execution statement, SELECT CASE, and could be very handy if it is used properly. The
SELECT CASE statement is also usually referred to as the CASE statement. The following is its syntactic form:

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 label-list-1, label-list-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 defined by PARAMETER. The type of these constants must be
identical to that of the selector.

● The first 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

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/select.html (1 of 4)8/5/2006 8:05:21 PM


SELECT CASE Statement

● If the result is not in any one of the label lists, there are two possibilities:
❍ if CASE DEFAULT is there, then the sequence of statements in statements-DEFAULT are executed,

followed by the statement following END SELECT


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

There are some notes for writing good Fortran programs:

● The constants listed in label lists must be unique


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

Examples

● 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

SELECT CASE (Class)


CASE (1)
WRITE(*,*) 'Freshman'
CASE (2)
WRITE(*,*) 'Sophomore'
CASE (3)
WRITE(*,*) 'Junior'
CASE (4)
WRITE(*,*) 'Senior'
CASE DEFAULT
WRITE(*,*) "Hmmmm, I don't know"
END SELECT
WRITE(*,*) 'Done'

● 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 (resp., PhD, MS and BS) is increased by 1. Otherwise,
Others is increased.

CHARACTER(LEN=4) :: Title
INTEGER :: DrMD = 0, PhD = 0, MS = 0, BS = 0, Others = 0

SELECT CASE (Title)


CASE ("DrMD")
DrMD = DrMD + 1
CASE ("PhD")
PhD = PhD + 1
CASE ("MS")

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/select.html (2 of 4)8/5/2006 8:05:21 PM


SELECT CASE Statement

MS = MS + 1
CASE ("BS")
BS = BS + 1
CASE DEFAULT
Others = Others + 1
END SELECT

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

INTEGER :: Number, Sign

SELECT CASE (Number)


CASE ( : -1)
Sign = -1
CASE (0)
Sign = 0
CASE (1 : )
Sign = 1
END SELECT
WRITE(*,*) "Sign = ", Sign

● If the value of c is one of the first ten letters (in lower case), 'One of the first ten letters' is displayed; if the value of
c is one of l, m, n, o, p, u, v, w, x, y, 'One of l, m, n, o, p, u, v, w, x, y' is displayed; if the value of c is one of z, q, r, s,
t, 'One of z, q, r, s, t' is displayed; and if the value of c is none of the above, 'Other 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

SELECT CASE (c)


CASE ('a' : 'j')
WRITE(*,*) 'One of the first ten letters'
CASE ('l' : 'p', 'u' : 'y')
WRITE(*,*) 'One of l, m, n, o, p, u, v, w, x, y'
CASE ('z', 'q' : 't')
WRITE(*,*) 'One of z, q, r, s, t'
CASE DEFAULT
WRITE(*,*) 'Other characters, which may not be letters'
END SELECT

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

INTEGER :: Number, Range

SELECT CASE (Number)


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

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/select.html (3 of 4)8/5/2006 8:05:21 PM


SELECT CASE Statement

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


Range = 2
CASE (-2:2)
Range = 3
CASE (3, 5)
Range = 4
CASE (4)
Range = 5
CASE DEFAULT
Range = 6
END SELECT

Here is the result:

Number Range Why?


CASE ( : -10,
<= -10 1
10 : )
-9, -8, -7, -6 6 CASE DEFAULT
-5, -4, -3 2 CASE (-5:-3, 6:9)
-2, -1, 0, 1,
3 CASE (-2: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)
CASE ( : -10,
>= 10 1
10 : )

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/select.html (4 of 4)8/5/2006 8:05:21 PM


Programming Example 1: Letter Grade Computation

Programming Example 1: Letter Grade Computation

Problem Statement

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 Grade
>= 90 A
< 90 and >=
AB
85
< 85 and >=
B
80
< 80 and >=
BC
75
< 75 and >=
C
70
< 70 and >=
CD
65
< 65 and >=
D
60
< 60 F

Write a program to read three marks, compute its average, round the average and use it to determine the corresponding
letter grade.

Solution

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

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/grade-1.html (1 of 3)8/5/2006 8:05:24 PM


Programming Example 1: Letter Grade Computation

! 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


Average = (Mark1 + Mark2 + Mark3) / 3.0

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.

Program Input and Output

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

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/grade-1.html (2 of 3)8/5/2006 8:05:24 PM


Programming Example 1: Letter Grade Computation

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

● The following output is generated from input 75.0, 60.0 and 45.0. The average is 60.0. The result after rounding is
60 and hence the letter grade is an D.

75.0 60.0 45.0

First Mark : 75.


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

Discussion

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.

In the program, REAL variable Average holds the average of the three input marks. To round the average value to be used
in the SELECT CASE statement, NINT(Average) is used. Other parts are obvious.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/grade-1.html (3 of 3)8/5/2006 8:05:24 PM


Programming Example 2: Character Testing

Programming Example 2: Character Testing

Problem Statement

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

Solution

! ------------------------------------------------------------
! 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
WRITE(*,*) 'A space is found : "', Input, '"'

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/chartest.html (1 of 2)8/5/2006 8:05:27 PM


Programming Example 2: Character Testing

CASE DEFAULT ! something else


WRITE(*,*) 'Something else found : "', Input, '"'
END SELECT

END PROGRAM CharacterTesting

Click here to download this program.

Program Input and Output

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 : "&"

Discussion

To be a vowel or a consonant, the input character must be a lower or upper case letter. So, the first CASE of the outer
SELECT CASE singles out all letters. Within the first CASE, another SELECT CASE is used to separate vowels from
consonants. Since a letter is either a vowel or a consonant, we use the shorter list (i.e., vowels) in the CASE label and let
CASE DEFAULT deal with the longer list of consonants.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/chartest.html (2 of 2)8/5/2006 8:05:27 PM


Repetitive Execution

Repetitive Execution

Select the topics you wish to review:

Repetitive Execution
Counting DO-Loop
Programming Examples:
Counting Positive and Negative Input Values
Computing Arithmetic, Geometric and Harmonic Means
Computing Factorial
General DO-Loop with EXIT
Programming Examples:
Determining the Minimum and Maximum of Input Data
Computing the Square Root of a Positive Number
Computing EXP(x)
Computing the Greatest Common Divisor of Two Positive Integers
Checking If a Positive Integer Is a Prime Number
Nested DO-Loop
Programming Examples:
Computing Classes Averages
Computing a Set of Values of EXP(x)
Armstrong Numbers
Finding All Primes in the Range of 2 and N
Finding all Prime factors of a Positive Integer
Handling End of File: the READ Statement Revisited
Computing Arithmetic, Geometric and Harmonic Means: Revisited
The DO-CYCLE Construct and a Programming Example (Optional)
Download my course overheads

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/loop.html8/5/2006 8:05:43 PM
Counting DO-Loop

Counting DO-Loop

There are two forms of loops, the counting loop and the general loop. The syntax of the counting loop is the following:

DO control-var = initial-value, final-value, [step-size]


statements
END DO

where control-var is an INTEGER variable, initial-value and final-value are two INTEGER expressions, and step-size is
also an INTEGER expression whose value cannot be zero. Note that step-size is optional. If it is omitted, the default value
is 1. statements is a sequence of statements and is usually referred to as the body of the DO-loop. You can use any
executable statement within a DO-loop, including IF-THEN-ELSE-END IF and even another DO-loop.

The following are a few simple examples:

● INTEGER variables Counter, Init, Final and Step are control-var, initial-value, final-value and step-size,
respectively.

INTEGER :: Counter, Init, Final, Step

READ(*,*) Init, Final, Step


DO Counter = Init, Final, Step
.....
END DO

● INTEGER variables i is the control-var. The initial-value and final-value are computed as the results of INTEGER
expressions Upper-Lower and Upper+Lower, respectively. Since step-size is omitted, it is assumed to be 1.

INTEGER :: i, Lower, Upper

Lower = ....
Upper = ....
DO i = Upper - Lower, Upper + Lower
.....
END DO

The meaning of this counting-loop goes as follows:

● Before the DO-loop starts, the values of initial-value, final-value and step-size are computed exactly once. More
precisely, during the course of executing the DO-loop, these values will not be re-computed.
● step-size cannot be zero.
● If the value of step-size is positive (i.e., counting up):
1. The control-var receives the value of initial-value
2. If the value of control-var is less than or equal to the value of final-value, the statements part is
executed. Then, the value of step-size is added to the value of control-var. Go back and compare the
values of control-var and final-value.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/count-do.html (1 of 5)8/5/2006 8:05:50 PM


Counting DO-Loop

3. If the value of control-var is greater than the value of final-value, the DO-loop completes and the
statement following END DO is executed.
● If the value of step-size is negative (i.e., counting down):
1. The control-var receives the value of initial-value
2. If the value of control-var is greater than or equal to the value of final-value, the statements part is
executed. Then, the value of step-size is added to the value of control-var. Go back and compare the
values of control-var and final-value.
3. If the value of control-var is less than the value of final-value, the DO-loop completes and the statement
following END DO is executed.

Examples

● In the following, the control-var is Count. It receives -3 before the loop starts. It goes down the loop body and
display the values of Count, Count*Count and Count*Count*Count. Thus, -3, 9, -27 are displayed. Then, 2 is
added to Count changing its value from -3 to -1. Since this new value of Count (=-1) is less than the final-
value, the loop body is executed and displays -1, 1, -1. Then, 2 is added to Count again, changing the value of
Count to 1(=(-1)+2). Since this new value is still less than the final-value, the loop body is executed again. This
time, it will display 1, 1, 1. Then, 2 is added to Count the third time, changing its value to 3. Since 3 is still less
than the final-value, 3, 9, 27 are displayed. After adding 2 to the value of Count the fourth time, the new value
of Count is finally greater than the final-value and the DO-loop completes.

INTEGER :: Count

DO Count = -3, 4, 2
WRITE(*,*) Count, Count*Count, Count*Count*Count
END DO

● In the following, since steps-size is omitted, it is assumed to be 1. Therefore, the control-var Iteration receives
3, 4, and 5 in this order.

INTEGER, PARAMETER :: Init = 3, Final = 5


INTEGER :: Iteration

DO Iteration = Init, Final


WRITE(*,*) 'Iteration ', Iteration
END DO

● The following uses two Fortran intrinsic functions MIN() and MAX(). It is a count-down loop. The initial-
value is the maximum of a, b and c, the final-value is the minimum of a, b and c, and the step-size is -2.
Therefore, if the READ statement reads 2, 7, 5 into a, b and , then MAX(a,b,c) and MIN(a,b,c) are 7 and 2,
respectively. As a result, control-var List will have values 7, 5, and 3.

INTEGER :: a, b, c
INTEGER :: List

READ(*,*) a, b, c
DO List = MAX(a, b, c), MIN(a, b, c), -2
WRITE(*,*) List

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/count-do.html (2 of 5)8/5/2006 8:05:50 PM


Counting DO-Loop

END DO

Frequently Used Loop Tricks

In addition to repeatedly processing some data as shown above, the DO-loop has some other uses as presented in the
following examples:

● Adding numbers: Suppose the value of INTEGER variable Number has been given elsewhere, perhaps with a
READ. The following code reads in Number integers and computes their sum into variable Sum.

INTEGER :: Count, Number, Sum, Input

Sum = 0
DO Count = 1, Number
READ(*,*) Input
Sum = Sum + Input
END DO

Sum is initialized to zero. For each iteration, the value of Input, which is read in with READ, is added to the
value of Sum.

For example, if the value of Number is 3, and the three input values are 3, 6, and 8 (on different lines), then
the final value of Sum is 17 = 3+6+8. Let us look at it closely. Initially, Count receives a value of 1. Since 1 is
less than the value of Number (=3), the loop body is executed. The READ statement reads the first input value
3 into Input and this value is added to Sum, changing its value from 0 to 1 (=0+1). Now, END DO is reached
and the step-size (=1) is added to Count. Hence, the new value of Count is 2.

Since Count is less than Number, the second input value is read into Input. Now, Input holds 6. Then, 6 is
added to the value of Sum, changing its value to 9 (=3+6). The next iteration reads in 8 and adds 8 to Sum.
The new value of Sum becomes 17 (=9+8).

A simple modification can compute the average of all input numbers:

INTEGER :: Count, Number, Sum, Input


REAL :: Average

Sum = 0
DO Count = 1, Number
READ(*,*) Input
Sum = Sum + Input
END DO
Average = REAL(Sum) / Number

The above seems obvious. But, please note the use of the function REAL() that converts an INTEGER to a
REAL. Without this conversion, Sum /Number is computed as dividing an integer by an integer, yielding an
integer result. Consult singe mode arithmetic expressions for details.
● Factorial: A simple variation could be used to compute the factorial of a positive integer. The factorial of an

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/count-do.html (3 of 5)8/5/2006 8:05:50 PM


Counting DO-Loop

integer N, written as N!, is defined to be the product of 1, 2, 3, ..., N-1, and N. More precisely, N! = N*(N-1)*
(N-2)*...*3*2*1.

INTEGER :: Factorial, N, I

Factorial = 1
DO I = 1, N
Factorial = factorial * I
END DO

In the above, the DO-loop iterates N times. The first iteration multiplies Factorial with 1, the second iteration
multiplies Factorial with 2, the third time with 3, ..., the i-th time with I and so on. Therefore, the values that
are multiplied with the initial value of Factorial are 1, 2, 3, ..., N. At the end of the DO, the value of Factorial
is 1*2*3*...*(N-1)*N.

Some Helpful Notes

There are certain things you should know about DO-loops.

● The step-size cannot be zero. The following is not a good practice:

INTEGER :: count

DO count = -3, 4, 0
...
END DO

● Do not change the value of the control-var. The following is not a good practice:

INTEGER :: a, b, c

DO a = b, c, 3
READ(*,*) a ! the value of a is changed
a = b-c ! the value of a is changed
END DO

● Do not change the value of any variable involved in initial-value, final-value and step-size. The following is not
a good practice:

INTEGER :: a, b, c, d, e

DO a = b+c, c*d, (b+c)/e


READ(*,*) b ! initial-value is changed
d = 5 ! final-value is changed
e = -3 ! step-size is changed
END DO

● When you have a count-down loop, make sure the step-size is negative. If you have a positive step-size, the

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/count-do.html (4 of 5)8/5/2006 8:05:50 PM


Counting DO-Loop

body of the DO-loop will not be executed. See the way of executing a DO loop above. The body of the following
DO will not be executed.

INTEGER :: i

DO i = 10, -10
.....
END DO

● While you can use REAL type for control-var, initial-value, final-value and step-size, it would be better not to
use this feature at all since it may be dropped in future Fortran standard. In the DO-loop below, x
successively receives -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75 and 1.0.

REAL :: x

DO x = -1.0, 1.0, 0.25


.....
END DO

You should not use this form of DO-loop in your programs. See the discussion of general DO for the details.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/count-do.html (5 of 5)8/5/2006 8:05:50 PM


Counting Positive and Negative Input Value

Counting Positive and Negative Input Values

Problem Statement

Given a set of integer input values, write a program to count the number of positive and negative values and compute their
sums.

The input is organized as follows:

● The first line gives the number of data values that follow
● Starting with the second line, each line contains an integer input value

For example, the following input shows that there are seven input values (i.e., the 7 on the first line), -6, 7, 2, -9, 0, 8 and 0.

7
-6
7
2
-9
0
8
0

Solution

! ---------------------------------------------------------
! This program counts the number of positive and negative
! input values and computes their sums.
! ---------------------------------------------------------

PROGRAM Counting
IMPLICIT NONE

INTEGER :: Positive, Negative


INTEGER :: PosSum, NegSum
INTEGER :: TotalNumber, Count
INTEGER :: Data

Positive = 0 ! # of positive items


Negative = 0 ! # of negative items
PosSum = 0 ! sum of all positive items
NegSum = 0 ! sum of all negative items

READ(*,*) TotalNumber ! read in # of items

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/count.html (1 of 3)8/5/2006 8:05:52 PM


Counting Positive and Negative Input Value

DO Count = 1, TotalNumber ! for each iteration


READ(*,*) Data ! read an item
WRITE(*,*) 'Input data ', Count, ': ', Data
IF (Data > 0) THEN ! if it is positive
Positive = Positive + 1 ! count it
PosSum = PosSum + Data ! compute their sum
ELSE IF (Data < 0) THEN ! if it is negative
Negative = Negative + 1 ! count it
NegSum = NegSum + Data ! compute their sum
END IF
END DO

WRITE(*,*) ! display results


WRITE(*,*) 'Counting Report:'
WRITE(*,*) ' Positive items = ', Positive, ' Sum = ', PosSum
WRITE(*,*) ' Negative items = ', Negative, ' Sum = ', NegSum
WRITE(*,*) ' Zero items = ', TotalNumber - Positive - Negative
WRITE(*,*)
WRITE(*,*) 'The total of all input is ', Positive + Negative

END PROGRAM Counting

Click here to download this program.

Program Input and Output

If the data shown above is stored in a file, say data.in and the above program is compiled to an executable count, then
executing

count < data.in

will generate the following output:

Input data 1: -6
Input data 2: 7
Input data 3: 2
Input data 4: -9
Input data 5: 0
Input data 6: 8
Input data 7: 0

Counting Report:
Positive items = 3 Sum = 17
Negative items = 2 Sum = -15
Zero items = 2

The total of all input is 5

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/count.html (2 of 3)8/5/2006 8:05:52 PM


Counting Positive and Negative Input Value

Discussion

In the program, Positive and Negative are used to count the number of positive and negative data items, and PosSum and
NegSum are used to compute their sums. The program first reads the number of input items into TotalNumber and uses it
as the final value in a DO-loop.

This loop iterates TotalNumber times. For each iteration, it reads in a new data into Data. The IF-THEN-ELSE-END IF
statement tests to see if it is positive or negative, adds 1 into the corresponding counter, and adds the value into the
corresponding sum. Note that the number of zero items are not counted, since TotalNumber - Positive - Negative gives the
number of zero items. The sum of all zero items are not calculated either, since it must be zero!

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/count.html (3 of 3)8/5/2006 8:05:52 PM


Computing Arithmetic, Geometric and Harmonic Means

Computing Arithmetic, Geometric and Harmonic Means

Problem Statement

The arithmetic mean (i.e., average), geometric mean and harmonic mean of a set of n numbers x1, x2, ..., xn are defined as
follows:

Since computing geometric mean requires taking square root, it is further required that all input data values must be
positive. As a result, this program must be able to ignore those non-positive items. However, this may cause all input items
ignored. Therefore, before computing the means, this program should have one more check to see if there are valid items.

Solution

! ----------------------------------------------------------
! This program reads a series of input data values and
! computes their arithmetic, geometric and harmonic means.
! Since geometric mean requires taking n-th root, all input
! data item must be all positive (a special requirement of
! this program , although it is not absolutely necessary).
! If an input item is not positive, it should be ignored.
! Since some data items may be ignored, this program also
! checks to see if no data items remain!
! ----------------------------------------------------------

PROGRAM ComputingMeans
IMPLICIT NONE

REAL :: X
REAL :: Sum, Product, InverseSum
REAL :: Arithmetic, Geometric, Harmonic
INTEGER :: Count, TotalNumber, TotalValid

Sum = 0.0 ! for the sum


Product = 1.0 ! for the product
InverseSum = 0.0 ! for the sum of 1/x
TotalValid = 0 ! # of valid items

READ(*,*) TotalNumber ! read in # of items

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/means-2.html (1 of 4)8/5/2006 8:05:56 PM


Computing Arithmetic, Geometric and Harmonic Means

DO Count = 1, TotalNumber ! for each item ...


READ(*,*) X ! read it in
WRITE(*,*) 'Input item ', Count, ' --> ', X
IF (X <= 0.0) THEN ! if it is non-positive
WRITE(*,*) 'Input <= 0. Ignored' ! ignore it
ELSE ! otherwise,
TotalValid = TotalValid + 1 ! count it in
Sum = Sum + X ! compute the sum,
Product = Product * X ! the product
InverseSum = InverseSum + 1.0/X ! and the sum of 1/x
END IF
END DO

IF (TotalValid > 0) THEN ! are there valid items?


Arithmetic = Sum / TotalValid ! yes, compute means
Geometric = Product**(1.0/TotalValid)
Harmonic = TotalValid / InverseSum

WRITE(*,*) 'No. of valid items --> ', TotalValid


WRITE(*,*) 'Arithmetic mean --> ', Arithmetic
WRITE(*,*) 'Geometric mean --> ', Geometric
WRITE(*,*) 'Harmonic mean --> ', Harmonic
ELSE ! no, display a message
WRITE(*,*) 'ERROR: none of the input is positive'
END IF

END PROGRAM ComputingMeans

Click here to download this program.

Program Input and Output

This program uses the same format of input as discussed in previous example. More precisely, the first line gives the
number of data items, followed by that number of input line on each which is a data value. Except for the first input value,
which gives the number of input, all other values are real numbers.

● If the input data is

5
1.0
2.0
3.0
4.0
5.0

it will generate the following output. In this input, all data values are positive and none of them is ignored.

Input item 1 --> 1.


Input item 2 --> 2.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/means-2.html (2 of 4)8/5/2006 8:05:56 PM


Computing Arithmetic, Geometric and Harmonic Means

Input item 3 --> 3.


Input item 4 --> 4.
Input item 5 --> 5.

No. of valid items --> 5


Arithmetic mean --> 3.
Geometric mean --> 2.6051712
Harmonic mean --> 2.18978071

● In the following input, the fourth value is negative.

6
1.0
2.0
3.0
-4.0
5.0
6.0

The output is shown below:

Input item 1 --> 1.


Input item 2 --> 2.
Input item 3 --> 3.
Input item 4 --> -4.
Input <= 0. Ignored
Input item 5 --> 5.
Input item 6 --> 6.

# of items read --> 6


# of valid items -> 5
Arithmetic mean --> 3.4000001
Geometric mean --> 2.82523465
Harmonic mean --> 2.27272725

● Now, let us try the following input in which all values are non-positive:

4
-1.0
-2.0
0.0
-3.0

We shall get the following output. The program correctly detects there is no valid data values and displays a
message.

Input item 1 --> -1.


Input <= 0. Ignored
Input item 2 --> -2.
Input <= 0. Ignored

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/means-2.html (3 of 4)8/5/2006 8:05:56 PM


Computing Arithmetic, Geometric and Harmonic Means

Input item 3 --> 0.E+0


Input <= 0. Ignored
Input item 4 --> -3.
Input <= 0. Ignored

ERROR: none of the input is positive

Discussion

This example is quite simple and does not require further explanation.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/means-2.html (4 of 4)8/5/2006 8:05:56 PM


Computing Factorial

Computing Factorial

Problem Statement

The factorial of a non-negative integer n, written as n!, is defined as follows:

Write a program that reads in an integer and computes its factorial. This program should detect if the input is negative and
display an error message.

Solution

! ----------------------------------------------------------
! Given a non-negative integer N, this program computes
! the factorial of N. The factorial of N, N!, is defined as
! N! = 1 x 2 x 3 x .... x (N-1) x N
! and 0! = 1.
! ----------------------------------------------------------

PROGRAM Factorial
IMPLICIT NONE

INTEGER :: N, i, Answer

WRITE(*,*) 'This program computes the factorial of'


WRITE(*,*) 'a non-negative integer'
WRITE(*,*)
WRITE(*,*) 'What is N in N! --> '
READ(*,*) N
WRITE(*,*)

IF (N < 0) THEN ! input error if N < 0


WRITE(*,*) 'ERROR: N must be non-negative'
WRITE(*,*) 'Your input N = ', N
ELSE IF (N == 0) THEN ! 0! = 1
WRITE(*,*) '0! = 1'
ELSE ! N > 0 here
Answer = 1 ! initially N! = 1
DO i = 1, N ! for each i = 1, 2, ..., N
Answer = Answer * i ! multiply i to Answer

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/fact.html (1 of 3)8/5/2006 8:05:59 PM


Computing Factorial

END DO
WRITE(*,*) N, '! = ', Answer
END IF

END PROGRAM Factorial

Click here to download this program.

Program Input and Output

● If the input is -5, a negative number, the program generates the following output indicating the input is wrong.

This program computes the factorial of


a non-negative integer

What is N in N! -->
-5

ERROR: N must be non-negative


Your input N = -5

● If the input is a zero, the output is 0! = 1.

This program computes the factorial of


a non-negative integer

What is N in N! -->
0

0! = 1

● If the input is 5, the factorial of 5 is 5!=1*2*3*4*5=120.

This program computes the factorial of


a non-negative integer

What is N in N! -->
5

5! = 120

● If the input is 15, the factorial of 15 is 15! = 1*2*3*...*13*14*15=2004310016

This program computes the factorial of


a non-negative integer

What is N in N! -->
15

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/fact.html (2 of 3)8/5/2006 8:05:59 PM


Computing Factorial

15! = 2004310016

Discussion

The basics of writing a factorial computation program has been discussed in a factorial example of counting DO.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/fact.html (3 of 3)8/5/2006 8:05:59 PM


General DO-Loop with EXIT

General DO-Loop with EXIT

The general DO-loop is actually very simple. But, to use it properly, you need to be very careful, since it may never stop.
The general DO-loop has a form as follows:

DO
statements
END DO

Between DO and END DO, there are statements. These statements are executed over and over without any chance to get
out of the DO-loop. Here is an example,

REAL :: x, y, z
DO
READ(*,*) x
y = x*x
z = x*x*x
WRITE(*,*) x, ' square = ', y, ' cube = ', z
END DO

One iteration of this loop consists of reading a value for x, computing its square and cube to y and z, respectively, and
displaying the results. Then, the execution goes back to the top and executes the four statements again. Consequently, this
loop is executed over and over and has no chance to stop at all. A loop that never stops is usually referred to as an infinite
loop. To stop the iteration of a DO-loop, we need something else.

The EXIT Statement

The EXIT is as simple as writing down the word EXIT. It is used to bail out the containing loop.

DO
statements-1
EXIT
statements-2
END DO

In the above, statements-1 is executed followed by the EXIT statement. Once the EXIT statement is reached, the control
leaves the inner-most DO-loop that contains the EXIT statement. Therefore, in the above case, statements-2 will never be
executed.

Since it must be some reason for bailing out a DO-loop, the EXIT statement is usually used with an IF or even an IF-
THEN-ELSE-END IF statement in one of the following forms. Note that these are not the only cases in which you can use
EXIT.

DO
statements-1

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/general-do.html (1 of 4)8/5/2006 8:06:01 PM


General DO-Loop with EXIT

IF (logical-expression) EXIT
statements-2
END DO

DO
statements-1
IF (logical-expression) THEN
statements-THEN
EXIT
END IF
statements-2
END DO

For each iteration, statements in statements-1 are executed, followed the evaluation of the logical-expression. If the result
is .FALSE., statements in statements-2 are executed. This completes one iteration and the control goes back to the top and
executes statements-1 again for next iteration.

If the result of evaluating logical-expression is .TRUE., the first form will executes EXIT, which immediately stops the
execution of the DO-loop. The next statement to be executed is the one following END DO.

For the second form, if the result of evaluating logical-expression is .TRUE., statements in statements-THEN are
executed followed by the EXIT statement, which brings the execution to the statement following END DO.
Therefore, statements in statements-THEN will do some "house-keeping" work before leaving the DO-loop. If there
is no "house-keeping" work, the first form will suffice.

Examples

● The following code reads in values into variable x until the input value becomes negative. All input values are
added to Sum. Note that the negative one is not added to Sum, since once the code sees such a negative value,
EXIT is executed.

INTEGER :: x, Sum

Sum = 0
DO
READ(*,*) x
IF (x < 0) EXIT
Sum = Sum + x
END DO

● The following is an example that "simulates" a counting DO-loop using REAL variables. Variable x is
initialized to the initial value Lower and serves as a control variable. Before any statement of the DO-loop is
executed, the value of x is checked to see if it is greater than the final value Upper. If it is, EXIT is executed,
leaving the loop. Otherwise, the loop body is executed and before goes back to the top, the control variable x
must be increased by the step size Step. This loop will display -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75 and 1.0,
each of them is on a separate line.

REAL, PARAMETER :: Lower = -1.0, Upper = 1.0, Step = 0.25

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/general-do.html (2 of 4)8/5/2006 8:06:01 PM


General DO-Loop with EXIT

REAL :: x

x = Lower ! initialize the control variable (DON'T FORGET)


DO
IF (x > Upper) EXIT ! is it > final-value?
WRITE(*,*) x ! no, do the loop body
x = x + Step ! an increase by step-size
END DO

● In many cases, your program may expect an input satisfying certain conditions. DO-loop can help a lot. The
following code keeps asking and checking if the input integer value is in the range of 0 and 10 inclusive. If it is
not, the program warns the user and reads again until the input is in the stated range.

INTEGER :: Input

DO
WRITE(*,*) 'Type an integer in the range of 0 and 10 please --> '
READ(*,*) Input
IF (0 <= Input .AND. Input <= 10) EXIT
WRITE(*,*) 'Your input is out of range. Try again'
END DO

Some Helpful Notes

● One of the most commonly seen problem is forgetting to change the logical-expression that may cause an
EXIT. The following DO-loop never stops and keeps displaying 5, 5, 5, 5, ..., forever. The reason? The value of
i is never changed.

INTEGER :: i

i = 5
DO
IF (i < -2) EXIT
WRITE(*,*) i
END DO

The following is another example:

INTEGER :: i = 1, j = 5

DO
IF (j < 0) EXIT
WRITE(*,*) i
i = i + 1
END DO

● Sometimes we just forget to initialize the control-var . We really do not know what would be displayed since
the value of i is unknown at the beginning of the DO and is certainly unknown after executing i = i - 1.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/general-do.html (3 of 4)8/5/2006 8:06:01 PM


General DO-Loop with EXIT

INTEGER :: i

DO
IF (i <= 3) EXIT
WRITE(*,*) i
i = i - 1
END DO

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/general-do.html (4 of 4)8/5/2006 8:06:01 PM


Determining the Minimum and Maximum of Input Data

Determining the Minimum and Maximum of Input Data

Problem Statement

Suppose we have a set of non-negative input integers terminated with a negative value. These input values are on separate
lines. Write a program to determine the number of input data items, excluding the negative one at the end, and compute the
minimum and the maximum. For example, the following input contains 7 data values with the seventh being negative. Of
the six non-negative ones, the minimum and maximum are 2 and 9, respectively.

5
3
9
2
7
4
-1

Solution

! ------------------------------------------------------
! This program reads in a number of integer input until
! a negative one, and determines the minimum and maximum
! of the input data values.
! ------------------------------------------------------

PROGRAM MinMax
IMPLICIT NONE

INTEGER :: Minimum, Maximum ! max and min


INTEGER :: Count ! # of data items
INTEGER :: Input ! the input value

Count = 0 ! initialize counter


DO ! for each iteration
READ(*,*) Input ! read in a new input
IF (Input < 0) EXIT ! if it is < 0, done.
Count = Count + 1 ! if >= 0, increase counter
WRITE(*,*) 'Data item #', Count, ' = ', Input
IF (Count == 1) THEN ! is this the 1st data?
Maximum = Input ! yes, assume it is the
Minimum = Input ! min and the max
ELSE ! no, not the 1st data
IF (Input > Maximum) Maximum = Input ! compare against the
IF (Input < Minimum) Minimum = Input ! existing min & max

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/minmax.html (1 of 2)8/5/2006 8:06:04 PM


Determining the Minimum and Maximum of Input Data

END IF
END DO

WRITE(*,*)
IF (Count > 0) THEN ! if at one data item found
WRITE(*,*) 'Found ', Count, ' data items'
WRITE(*,*) ' Maximum = ', Maximum
WRITE(*,*) ' Minimum = ', Minimum
ELSE
WRITE(*,*) 'No data item found.' ! no data item found
END IF

END PROGRAM MinMax

Click here to download this program.

Program Input and Output

If this program uses the input shown at the beginning, it will generate the following output:

Data item #1 = 5
Data item #2 = 3
Data item #3 = 9
Data item #4 = 2
Data item #5 = 7
Data item #6 = 4

Found 6 data items


Maximum = 9
Minimum = 2

Discussion

● The data reading scheme is easy and will not be discussed. It has been discussed in an example of general DO.
● Variable Count is used for counting the number of data items.
● Once a non-negative item is read in, the value of Count is increased by 1 and the input value is displayed.
● If this is the first value (i.e., Count being 1), it is the maximum and the minimum value we have seen so far.
Therefore, the value of Input is saved in Minimum and Maximum which hold the minimum and maximum values
seen so far.
● If it is not the first input value, then Input is compared against Minimum and Maximum. If Input is less than
Minimum, then the new value is less than the minimum so far and should become the new minimum. Likewise, if
Input is greater than Maximum, then the new value is greater than the maximum so far and should become the new
maximum. These activities are handled in the ELSE part.
● After all input are read, Count should be checked again to see if there is any input value at all. If there are, the count,
minimum and maximum are displayed; otherwise, a message is displayed.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/minmax.html (2 of 2)8/5/2006 8:06:04 PM


Computing the Square Root of a Positive Number

Computing the Square Root of a Positive Number

Problem Statement

The square root of a positive number b can be computed with Newton's formula:

where x above starts with a "reasonable" guess. In fact, you can always start with b or some other value, say 1.

With b and a guess value x, a new guess value is computed with the above formula. This process continues until the new
guess value and the current guess value are very close. In this case, either one can be considered as an approximation of the
square root of b.

Write a program that reads in a REAL value and a tolerance, and computes the square root until the absolute error of two
adjacent guess values is less than the tolerance value.

Solution

! ---------------------------------------------------------
! This program uses Newton's method to find the square
! root of a positive number. This is an iterative method
! and the program keeps generating better approximation
! of the square root until two successive approximations
! have a distance less than the specified tolerance.
! ---------------------------------------------------------

PROGRAM SquareRoot
IMPLICIT NONE

REAL :: Input, X, NewX, Tolerance


INTEGER :: Count

READ(*,*) Input, Tolerance

Count = 0 ! count starts with 0


X = Input ! X starts with the input value
DO ! for each iteration
Count = Count + 1 ! increase the iteration count
NewX = 0.5*(X + Input/X) ! compute a new approximation
IF (ABS(X - NewX) < Tolerance) EXIT ! if they are very close, exit
X = NewX ! otherwise, keep the new one
END DO

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/sqrt.html (1 of 2)8/5/2006 8:06:07 PM


Computing the Square Root of a Positive Number

WRITE(*,*) 'After ', Count, ' iterations:'


WRITE(*,*) ' The estimated square root is ', NewX
WRITE(*,*) ' The square root from SQRT() is ', SQRT(Input)
WRITE(*,*) ' Absolute error = ', ABS(SQRT(Input) - NewX)

END PROGRAM SquareRoot

Click here to download this program.

Program Input and Output

If the input are 10.0 for b and 0.00001 for the tolerance, the following output shows that it requires 6 iterations to reach an
approximation of square root of 10. Comparing the result with the one obtained from Fortran intrinsic function SQRT(), the
absolute error is zero.

After 6 iterations:
The estimated square root is 3.1622777
The square root from SQRT() is 3.1622777
Absolute error = 0.E+0

If the input are 0.5 for b and 0.00001 for the tolerance, it takes 4 iterations to reach an approximation of the square root of
0.5. The value from using Fortran intrinsic function SQRT() is 0.707106769 and again the absolute error is 0.

After 4 iterations:
The estimated square root is 0.707106769
The square root from SQRT() is 0.707106769
Absolute error = 0.E+0

Discussion

● This program uses X to hold the input value for b and uses NewX to hold the new guess value. The initial guess is the
input value.
● From the current guess, using Newton's formula, the new guess is compared as

NewX = 0.5*(X + Input/X)

● Then, the absolute error of X and NewX is computed. If it is less than the tolerance value, EXIT the loop and display
the results. Otherwise, the current guess is replaced with the new guess and go back for the next iteration.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/sqrt.html (2 of 2)8/5/2006 8:06:07 PM


Computing EXP(x)

Computing EXP(x)

Problem Statement

The exponential function, EXP(x), is defined to be the sum of the following infinite series:

Write a program that reads in a REAL value and computes EXP() of that value using the series until the absolute value of a
term is less than a tolerance value, say 0.00001.

Solution

! ---------------------------------------------------------
! This program computes exp(x) for an input x using the
! infinite series of exp(x). This program adds the
! terms together until a term is less than a specified
! tolerance value. Thus, two values are required:
! the value for x and a tolerance value. In this program,
! he tolerance value is set to 0.00001 using PARAMETER.
! ---------------------------------------------------------

PROGRAM Exponential
IMPLICIT NONE

INTEGER :: Count ! # of terms used


REAL :: Term ! a term
REAL :: Sum ! the sum of series
REAL :: X ! the input x
REAL, PARAMETER :: Tolerance = 0.00001 ! tolerance

READ(*,*) X ! read in x
Count = 1 ! the first term is 1 and counted
Sum = 1.0 ! thus, the sum starts with 1
Term = X ! the second term is x
DO ! for each term
IF (ABS(Term) < Tolerance) EXIT ! if too small, exit
Sum = Sum + Term ! otherwise, add to sum
Count = Count + 1 ! count indicates the next term
Term = Term * (X / Count) ! compute the value of next term
END DO

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/exp.html (1 of 3)8/5/2006 8:06:12 PM


Computing EXP(x)

WRITE(*,*) 'After ', Count, ' iterations:'


WRITE(*,*) ' Exp(', X, ') = ', Sum
WRITE(*,*) ' From EXP() = ', EXP(X)
WRITE(*,*) ' Abs(Error) = ', ABS(Sum - EXP(X))

END PROGRAM Exponential

Click here to download this program.

Program Input and Output

If the input value is 10.0, the following output shows that it requires 35 iterations to reach EXP(10.0)=22026.4648.
Comparing the result with the one obtained from Fortran intrinsic function EXP(), the absolute error is zero.

After 35 iterations:
Exp(10.) = 22026.4648
From EXP() = 22026.4648
Abs(Error) = 0.E+0

If the input is -5.0, it takes 21 iterations to reach EXP(-5.0)=6.744734943E-3. The value from using Fortran intrinsic function
is 6.737946998E-3 and the absolute error is 6.787944585E-6.

After 21 iterations:
Exp(-5.) = 6.744734943E-3
From EXP() = 6.737946998E-3
Abs(Error) = 6.787944585E-6

Discussion

● One obvious way of writing this program is computing each term directly using the formula xi/i!. However, this is not
a wise way, since both xi and i! could get very large when x or i is large. One way to overcome this problem is
rewriting the term as follows:

Therefore, the (i+1)-th term is equal to the product of the i-th term and x/(i+1). In the program, variable Term is used
to save the value of the current term and is updated with

Term = Term * (X / Count)

where Count is the value of i+1.


● Variable Sum is used to accumulate the values of terms.
● Since the tolerance value is usually small, the first term whose value is 1 cannot be less than the tolerance value.
Therefore, the computation starts with the second term and 1 is saved to Sum.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/exp.html (2 of 3)8/5/2006 8:06:12 PM


Computing EXP(x)

● Count indicates which term is under consideration. Its plays the role of i in the infinite series shown above.
● Since the computation starts with the first term, the value of the first term, x, is saved to Term.
● For each iteration, the absolute value of Term is checked to see if it is less than the tolerance value Tolerance. If it is,
the computation is done and EXIT.
● Otherwise, this term is added to Sum and prepare for the next term. Before this, Count is increased by one to point to
the next term and consequently the next term is computed as Term * (X / Count).

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/exp.html (3 of 3)8/5/2006 8:06:12 PM


Computing the Greatest Common Divisor of Two Positive Integers

Computing the Greatest Common Divisor of Two Positive


Integers

Problem Statement

The Greatest Common Divisor, GCD for short, of two positive integers can be computed with Euclid's division algorithm.
Let the given numbers be a and b, a >= b. Euclid's division algorithm has the following steps:

1. Compute the remainder c of dividing a by b.


2. If the remainder c is zero, b is the greatest common divisor.
3. If c is not zero, replace a with b and b with the remainder c. Go back to step (1).

Write a program that reads in two integers and computes their greatest common divisor. Note that these two input could be
in any order.

Solution

! ---------------------------------------------------------
! This program computes the GCD of two positive integers
! using the Euclid method. Given a and b, a >= b, the
! Euclid method goes as follows: (1) dividing a by b yields
! a reminder c; (2) if c is zero, b is the GCD; (3) if c is
! no zero, b becomes a and c becomes c and go back to
! Step (1). This process will continue until c is zero.
! ---------------------------------------------------------

PROGRAM GreatestCommonDivisor
IMPLICIT NONE

INTEGER :: a, b, c

WRITE(*,*) 'Two positive integers please --> '


READ(*,*) a, b
IF (a < b) THEN ! since a >= b must be true, they
c = a ! are swapped if a < b
a = b
b = c
END IF

DO ! now we have a <= b


c = MOD(a, b) ! compute c, the reminder
IF (c == 0) EXIT ! if c is zero, we are done. GCD = b
a = b ! otherwise, b becomes a
b = c ! and c becomes b

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/gcd.html (1 of 3)8/5/2006 8:06:14 PM


Computing the Greatest Common Divisor of Two Positive Integers

END DO ! go back

WRITE(*,*) 'The GCD is ', b

END PROGRAM GreatestCommonDivisor

Click here to download this program.

Program Input and Output

● If the input values are 46332 and 71162, the computed GCD is 26.

Two positive integers please -->


46332 71162

The GCD is 26

● If the input values are 128 and 32, the GCD is 32.

Two positive integers please -->


128 32

The GCD is 32

● If the input values are 100 and 101, the GCD is 1 and 100 and 101 are relatively prime.

Two positive integers please -->


100 101

The GCD is 1

● If the input values are 97 and 97, the GCD is of course 97.

Two positive integers please -->


97 97

The GCD is 97

Discussion

● Since there is no specific order for the two input values, it is possible that a may be less than b. In this case, these
two values must be swapped.
● Thus, before entering the DO-loop, we are sure that a >= b holds.
● Then, the remainder is computed and stored to c. If c is zero, the program EXITs and displays the value of b as the
GCD. The remainder is computed using Fortran intrinsic function MOD().
● If c is not zero, b becomes a and c becomes b, and reiterates.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/gcd.html (2 of 3)8/5/2006 8:06:14 PM


Computing the Greatest Common Divisor of Two Positive Integers

● If we need to display the result as follows:

The GCD of 46332 and 71162 is 26

would the following change to the WRITE statement work?

WRITE(*,*) 'The GCD of ', a, ' and ', b, ' is ', b

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/gcd.html (3 of 3)8/5/2006 8:06:14 PM


Checking If a Positive Integer Is a Prime Number

Checking If a Positive Integer Is a Prime Number

Problem Statement

An positive integer greater than or equal to 2 is a prime number if the only divisor of this integer is 1 and itself.

Write a program that reads in an arbitrary integer and determines if it is a prime number.

Solution

! --------------------------------------------------------------------
! Given an integer, this program determines if it is a prime number.
! This program first makes sure the input is 2. In this case, it is
! a prime number. Then, it checks to see the input is an even
! number. If the input is odd, then this program divides the input
! with 3, 5, 7, ....., until one of two conditions is met:
! (1) if one these odd number evenly divides the input, the
! input is not a prime number;
! (2) if the divisor is greater than the square toot of the
! input, the input is a prime.
! --------------------------------------------------------------------

PROGRAM Prime
IMPLICIT NONE

INTEGER :: Number ! the input number


INTEGER :: Divisor ! the running divisor

READ(*,*) Number ! read in the input


IF (Number < 2) THEN ! not a prime if < 2
WRITE(*,*) 'Illegal input'
ELSE IF (Number == 2) THEN ! is a prime if = 2
WRITE(*,*) Number, ' is a prime'
ELSE IF (MOD(Number,2) == 0) THEN ! not a prime if even
WRITE(*,*) Number, ' is NOT a prime'
ELSE ! we have an odd number here
Divisor = 3 ! divisor starts with 3
DO ! divide the input number
IF (Divisor*Divisor > Number .OR. MOD(Number, Divisor) == 0) EXIT
Divisor = Divisor + 2 ! increase to next odd
END DO
IF (Divisor*Divisor > Number) THEN ! which condition fails?
WRITE(*,*) Number, ' is a prime'
ELSE
WRITE(*,*) Number, ' is NOT a prime'
END IF

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/prime-1.html (1 of 3)8/5/2006 8:06:16 PM


Checking If a Positive Integer Is a Prime Number

END IF
END PROGRAM Prime

Click here to download this program.

Program Input and Output

● If the input value is -1, the output is a message saying the input is not legal.

Illegal input

● If the input is 2, it is a prime number.

2 is a prime

● If the input is 3, it is also a prime number.

3 is a prime

● If the input is 46, it is not a prime number since it is divisible by 2.

46 is NOT a prime

● If the input is 97, it is a prime number.

97 is a prime

● If the input is 9797, it is not a prime since it is divisible by 97.

9797 is NOT a prime

Discussion

● Since the input is an arbitrary integer, the program first makes sure its value is greater than or equal to 2; otherwise, a
message is displayed.
● If the input is greater than or equal to 2, the program checks if it is actually equal to 2. If it is, just reports "2 is a
prime".
● The next step is screening out all even numbers. Note that 2 has been checked before the control gets to the second
ELSE-IF. If the input is divisible by 2, it is not a prime number.
● If the control can reach here, the input is an odd number greater than or equal to 3. Then, the program uses 3, 5, 7, 9,
11, ... these odd numbers as divisors to divide the input value stored in Number. These divisors are successively
stored in Divisor.
● Of course, these divisors should start with 3; but, the question is when to stop. A naive answer would be "let us try up
to Number-1" This is too slow since Number cannot be evenly divided by Number-1.

A better choice is the square root of Number? Why is this strange value? If Number is divisible by a, then we can

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/prime-1.html (2 of 3)8/5/2006 8:06:16 PM


Checking If a Positive Integer Is a Prime Number

write Number=a*b for some b. If a is less than or equal to b, then a must be smaller than or equal to the square root
of Number.

Therefore, the upper limit of Divisor is the square root of Number. Stated in a slightly different way, it is "the square
of Divisor is less than or equal to Number". This is better since it only uses integer arithmetic, while the one using
square root involves REAL numbers.
● In the DO-loop, the value for Divisor starts with 3. As long as the square of Divisor is less than or equal to Number
and Number is not divisible by Divisor, the iteration continues.

Since Divisor can only be odd numbers, step-size is 2.

This loop continues until one of the two conditions holds. If Divisor*Divisor > Number holds, then all odd numbers
that are greater than or equal to 3 and less than or equal to the square root of Number have been tried and none of
them can evenly divide Number. Therefore, Number is a prime number.

If MOD(Number,Divisor) == 0 holds, Divisor divides Number and Number is not a prime.


● Let us take a look at a few examples:
1. Let Number be 3. Divisor starts with 3. Since condition Divisor*Divisor > Number holds immediately, 3 is a
prime number.
2. Let Number be 5. Divisor starts with 3. Since condition Divisor*Divisor > Number holds immediately, 5 is a
prime number.
3. Let Number be 11. Divisor starts with 3. In the first iteration, both Divisor*Divisor > Number and MOD
(Number,Divisor) == 0 fail. So, Divisor is increased by 2, becoming 5. In the second iteration,
Divisor*Divisor > Number holds and 11 is a prime.
4. Let Number be 91. Divisor starts with 3. In the first iteration, both Divisor*Divisor > Number and MOD
(Number,Divisor) == 0 fail. So, Divisor is increased by 2, becoming 5. In the second iteration, both conditions
still fail and Divisor is increased to 7. In the third iteration, MOD(Number,Divisor) == 0 holds and 91 is not a
prime.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/prime-1.html (3 of 3)8/5/2006 8:06:16 PM


Nested DO-Loops

Nested DO-Loops

Just like an IF-THEN-ELSE-END IF can contain another IF-THEN-ELSE-END IF (see nested IF for the details), a DO-
loop can contain other DO-loops in its body. The body of the contained DO-loop, usually referred to as the nested DO-
loop, must be completely inside the containing DO-loop. Note further that an EXIT statement only brings the control out of
the inner-most DO-loop that contains the EXIT statement.

Suppose we have the following nested DO loops:

DO
statements-1
DO
statement-2
END DO
statement-3
END DO

Each iteration of the outer DO starts with statements-1. When the control reaches the inner DO, statements-2 is executed
until some condition of the inner DO brings the control out of it. Then, statements-3 is executed and this completes one
iteration. Any EXIT in the inner DO brings the control out of the inner DO to the first statement in statement-3.

The following are a few simple examples:

● In the following nested loops, the outer one has i running from 1 to 9 with step size 1. For each iteration, say the i-th
one, the inner loop iterates 9 times with values of j being 1, 2, 3, 4, 5, 6, 7, 8, 9. Therefore, with i fixed, the
WRITE is executed 9 times and the output consists of i*1, i*2, i*3, ..., i*9.

INTEGER :: i, j

DO i = 1, 9
DO j = 1, 9
WRITE(*,*) i*j
END DO
END DO

Once this is done, the value of i is advanced to the next one, and the inner loop will iterate 9 times again
displaying the product of the new i and 1, 2, 3,4 ..., 9.

The net effect is a multiplication table. For i=1, the value if 1*1, 1*2, 1*3, ..., 1*9 are displayed; for i=2, the
displayed values are 2*1, 2*2, 2*3, ..., 2*9; ...; for i=9, the displayed values are 9*1, 9*2, 9*3, ..., 9*9.

● The following shows a nested DO-loop. The outer one lets u run from 2 to 5. For each u, the inner DO lets v
runs from 1 to u-1. Therefore, when u is 2, the values for v is from 1 to 1. When u is 3, the values for v are 1
and 2. When u is 4, the values for v are 1, 2, and 3. Finally, when u is 5, the values for v are 1, 2, 3 and 4.

INTEGER :: u, v

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/nested-do.html (1 of 3)8/5/2006 8:06:20 PM


Nested DO-Loops

INTEGER :: a, b, c

DO u = 2, 5
DO v = 1, u-1
a = 2*u*v
b = u*u - v*v
c = u*u + v*v
WRITE(*,*) a, b, c
END DO
END DO

The above discussion can be summarized in the following table:

u Values for v
2 1
3 1 2
4 1 2 3
5 1 2 3 4

For each pair of u and v, the inner loop computes a, b and c. Thus, it will generate the following result (please
verify it):

u v a b c
2 1 4 3 5
1 6 8 10
3
2 12 5 13
1 8 15 17
4 2 16 12 20
3 24 7 25
1 10 24 26
2 20 21 29
5
3 30 16 34
4 40 9 41

● It is obvious that the inner DO-loop computes the sum of all integers in the range of 1 and i (i.e., Sum is equal
to 1+2+3+...+i). Since i runs from 1 to 10, the following loop computes ten sums: 1, 1+2, 1+2+3, 1+2+3+4, ...., 1
+2+3+...+9, and 1+2+3+...+9+10.

INTEGER :: i, j, Sum

DO i = 1, 10
Sum = 0
DO j = 1, i
Sum = Sum + j

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/nested-do.html (2 of 3)8/5/2006 8:06:20 PM


Nested DO-Loops

END DO
WRITE(*,*) Sum
END DO

● The program below uses Newton's method for computing the square root of a positive number. In fact, it
computes the square roots of the numbers 0.1, 0.1, ..., 0.9 and 1.0.

REAL :: Start = 0.1, End = 1.0, Step = 0.1


REAL :: X, NewX, Value

Value = Start
DO
IF (Value > End) EXIT
X = Value
DO
NewX = 0.5*(X + Value/X)
IF (ABS(X - NewX) < 0.00001) EXIT
X = NewX
EBD DO
WRITE(*,*) 'The square root of ', Value, ' is ', NewX
Value = Value + Step
END DO

Newton's method is taken directly from the programming example, where X is the current guess, NewX is the
new guess, and Value is the number for square root computation. The EXIT statement brings the execution of
the inner DO to the WRITE statement.

If the inner loop is removed, we have the outer loop as follows:

REAL :: Start = 0.1, End = 1.0, Step = 0.1


REAL :: X, NewX, Value

Value = Start
DO
IF (Value > End) EXIT
!
! the inner loop computes the result in NewX
!
WRITE(*,*) 'The square root of ', Value, ' is ', NewX
Value = Value + Step
END DO

It is clear that the value of Value starts with 0.1 and have a step size 0.1 until 1.0. Thus, the values of Value
are 0.1, 0.2, 0.3, ..., 0.9 and 1.0. For each value of Value, the inner loop computes the square root of Value. The
EXIT statement in the outer loop brings the control out of the outer loop.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/nested-do.html (3 of 3)8/5/2006 8:06:20 PM


Computing Classes Averages

Computing Classes Averages

Problem Statement

There are four sessions of CS110 and CS201, each of which has a different number of students. Suppose all students take three
exams. Someone has prepared a file that records the exam scores of all students. This file has a form as follows:

4
3
97.0 87.0 90.0
100.0 78.0 89.0
65.0 70.0 76.0
2
100.0 100.0 98.0
97.0 85.0 80.0
4
78.0 75.0 90.0
89.0 85.0 90.0
100.0 97.0 98.0
56.0 76.0 65.0
3
60.0 65.0 50.0
100.0 99.0 96.0
87.0 74.0 81.0

The first number 4 gives the number of classes in this file. For each class, it starts with an integer, giving the number of
students in that class. Thus, the first class has 3 students, the second has 2, the third has 4 and the fourth has 3. Following the
number of students, there are that number of lines each of which contains the three scores of a student.

Write a program that reads in a file of this form and computes the following information:

1. the average of each student;


2. the class average of each exam; and
3. the grant average of the class.

Click here to download this data file.

Solution

! ----------------------------------------------------------
! This program computes the average of each student and the
! the average of the class. The input file starts with an
! integer giving the number of classes. For each class, the
! input starts with an integer giving the number of students
! of that class, followed that number of lines on each of
! which there are three scores. This program reads in the

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/means-3.html (1 of 4)8/5/2006 8:06:22 PM


Computing Classes Averages

! scores and computes their average and also the class


! averages of each score and the grant average of the class.
! ----------------------------------------------------------

PROGRAM ClassAverage
IMPLICIT NONE

INTEGER :: NoClass ! the no. of classes


INTEGER :: NoStudent ! the no. of students in each class
INTEGER :: Class, Student ! DO control variables
REAL :: Score1, Score2, Score3, Average
REAL :: Average1, Average2, Average3, GrantAverage

READ(*,*) NoClass ! read in the # of classes


DO Class = 1, NoClass ! for each class, do the following
READ(*,*) NoStudent ! the # of student in this class
WRITE(*,*)
WRITE(*,*) 'Class ', Class, ' has ', NoStudent, ' students'
WRITE(*,*)
Average1 = 0.0 ! initialize average variables
Average2 = 0.0
Average3 = 0.0
DO Student = 1, NoStudent ! for each student in this class
READ(*,*) Score1, Score2, Score3 ! read in his/her scores
Average1 = Average1 + Score1 ! prepare for class average
Average2 = Average2 + Score2
Average3 = Average3 + Score3
Average = (Score1 + Score2 + Score3) / 3.0 ! average of this one
WRITE(*,*) Student, Score1, Score2, Score3, Average
END DO
WRITE(*,*) '----------------------'
Average1 = Average1 / NoStudent ! class average of score1
Average2 = Average2 / NoStudent ! class average of score2
Average3 = Average3 / NoStudent ! class average of score3
GrantAverage = (Average1 + Average2 + Average3) / 3.0
WRITE(*,*) 'Class Average: ', Average1, Average2, Average3
WRITE(*,*) 'Grant Average: ', GrantAverage
END DO

END PROGRAM ClassAverage

Click here to download this program.

Program Input and Output

The input shown above should produce the following output:

Class 1 has 3 students

1, 97., 87., 90., 91.3333359


2, 100., 78., 89., 89.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/means-3.html (2 of 4)8/5/2006 8:06:22 PM


Computing Classes Averages

3, 65., 70., 76., 70.3333359


----------------------
Class Average: 87.3333359, 78.3333359, 85.
Grant Average: 83.5555573

Class 2 has 2 students

1, 100., 100., 98., 99.3333359


2, 97., 85., 80., 87.3333359
----------------------
Class Average: 98.5, 92.5, 89.
Grant Average: 93.3333359

Class 3 has 4 students

1, 78., 75., 90., 81.


2, 89., 85., 90., 88.
3, 100., 97., 98., 98.3333359
4, 56., 76., 65., 65.6666641
----------------------
Class Average: 80.75, 83.25, 85.75
Grant Average: 83.25

Class 4 has 3 students

1, 60., 65., 50., 58.3333321


2, 100., 99., 96., 98.3333359
3, 87., 74., 81., 80.6666641
----------------------
Class Average: 82.3333359, 79.3333359, 75.6666641
Grant Average: 79.1111145

Discussion

This is a relatively easy problem. Here is an analysis in case you need it.

Since for each class we need to compute the average of each student, the class average of each exam, and the grant average of
the whole class, we might immediately come up the following scheme:

READ(*,*) NoClass
DO Class = 1, NoClass
compute various average for this class
display exam averages and class the grant average
END DO

Thus, "compute various average for the class" becomes the job of the inner loop. This loop should read in the scores of each
student and do some computation as follows:

READ(*,*) NoStudent
DO Student = 1, NoStudent

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/means-3.html (3 of 4)8/5/2006 8:06:22 PM


Computing Classes Averages

READ(*,*) Score1, Score2, Score3


compute the average of this student
compute the exam averages
END DO

Now, the only trouble is how to compute the exam averages. In fact, this inner loop has no way to compute the exam averages
directly; but, it could compute the sum of the scores of a particular exam. After this inner loop ends, the outer loop could divide
the sum with the number of students to obtain the average. To accumulate these sums, we need to initialize variables. Thus, the
result is:

Average1 = 0.0
Average2 = 0.0
Average3 = 0.0
DO Student = 1, NoStudent
READ(*,*) Score1, Score2, Score3
Average1 = Average1 + Score1
Average2 = Average2 + Score2
Average3 = Average3 + Score3
Average = (Score1 + Score2 + Score3) / 3.0
WRITE(*,*) Student, Score1, Score2, Score3, Average
END DO
WRITE(*,*) '----------------------'
Average1 = Average1 / NoStudent
Average2 = Average2 / NoStudent
Average3 = Average3 / NoStudent
GrantAverage = (Average1 + Average2 + Average3) / 3.0

In the above, Average1, Average2 and Average3 are for the exam averages. They must be initialized right before entering the
inner DO-loop, since the exam averages are computed for each class. The actual average is computed right after the inner DO-
loop by dividing Average1, Average2 and Average3 with the number of students NoStudents. Once we have the exam
averages, the grant average is computed as the average of these exam averages.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/means-3.html (4 of 4)8/5/2006 8:06:22 PM


Computing a Set of Values of EXP(x)

Computing a Set of Values of EXP(x)

Problem Statement

In a previous example we have discussed the way of using infinite series for computing the exponential function EXP(x). The
exponential function, EXP(x), is usually defined to be the sum of the following infinite series:

Write a program that reads in an initial value Begin, a final value End and a step size Step, and computes the exponential
function value at Begin, Begin+Step, Begin+2*Step, ...

Solution

! --------------------------------------------------------------
! This program computes exp(x) for a range of x. The range
! is in the form of beginning value, final value and step size.
! For each value in this range, the infinite series of exp(x)
! is used to compute exp(x) up to a tolerance of 0.00001.
! This program display the value of x, the exp(x) from infinite
! series, the exp(x) from Fortran's intrinsic function exp(x),
! the absolute error, and the relative error.
! --------------------------------------------------------------

PROGRAM Exponential
IMPLICIT NONE

INTEGER :: Count ! term count


REAL :: Term ! a term
REAL :: Sum ! the sum of series
REAL :: X ! running value
REAL :: ExpX ! EXP(X)
REAL :: Begin, End, Step ! control values
REAL, PARAMETER :: Tolerance = 0.00001 ! tolerance

WRITE(*,*) 'Initial, Final and Step please --> '


READ(*,*) Begin, End, Step

X = Begin ! X starts with the beginning value


DO
IF (X > End) EXIT ! if X is > the final value, EXIT
Count = 1 ! the first term is 1 and counted
Sum = 1.0 ! thus, the sum starts with 1

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/exp-2.html (1 of 3)8/5/2006 8:06:26 PM


Computing a Set of Values of EXP(x)

Term = X ! the second term is x


ExpX = EXP(X) ! the exp(x) from Fortran's EXP()
DO ! for each term
IF (ABS(Term) < Tolerance) EXIT ! if too small, exit
Sum = Sum + Term ! otherwise, add to sum
Count = Count + 1 ! count indicates the next term
Term = Term * (X / Count) ! compute the value of next term
END DO

WRITE(*,*) X, Sum, ExpX, ABS(Sum-ExpX), ABS((Sum-ExpX)/ExpX)

X = X + Step
END DO

END PROGRAM Exponential

Click here to download this program.

Program Input and Output

If the input for Begin, End and Step are -1.0, 1.0 and 0.1, the program would generate the following output.

Initial, Final and Step please -->


-1., 0.367881894, 0.36787945, 2.443790436E-6, 6.642911103E-6
-0.899999976, 0.406570643, 0.40656966, 9.834766388E-7, 2.41896214E-6
-0.799999952, 0.449325144, 0.449328989, 3.844499588E-6, 8.556090506E-6
-0.699999928, 0.496584028, 0.496585339, 1.311302185E-6, 2.640638058E-6
-0.599999905, 0.5488168, 0.548811674, 5.125999451E-6, 9.340179531E-6
-0.499999911, 0.606532216, 0.606530726, 1.490116119E-6, 2.456785978E-6
-0.399999917, 0.670314729, 0.670320094, 5.36441803E-6, 8.002770301E-6
-0.299999923, 0.740817249, 0.740818262, 1.013278961E-6, 1.367783398E-6
-0.199999928, 0.818733335, 0.818730831, 2.503395081E-6, 3.05765343E-6
-9.999992698E-2, 0.904833436, 0.904837489, 4.053115845E-6, 4.479385552E-6
7.450580597E-8, 1., 1.00000012, 1.192092896E-7, 1.192092753E-7
0.100000076, 1.10516667, 1.10517097, 4.291534424E-6, 3.883140835E-6
0.200000077, 1.22140002, 1.22140288, 2.861022949E-6, 2.342407242E-6
0.300000072, 1.34985793, 1.34985888, 9.536743164E-7, 7.064992928E-7
0.400000066, 1.4918189, 1.49182475, 5.841255188E-6, 3.915510206E-6
0.50000006, 1.64871967, 1.64872134, 1.668930054E-6, 1.012257258E-6
0.600000083, 1.82211316, 1.822119, 5.841255188E-6, 3.205748499E-6
0.700000107, 2.01375127, 2.01375294, 1.668930054E-6, 8.287660194E-7
0.800000131, 2.22553682, 2.22554111, 4.291534424E-6, 1.928310667E-6
0.900000155, 2.45960236, 2.45960355, 1.192092896E-6, 4.846687034E-7

The first column shows the data values (i.e., -1.0, -0.9, ..., 1.0), the second is the values from using infinite series with a tolerance
value 0.00001, the third column contains the values from Fortran's intrinsic function EXP(), the forth column has the absolute
errors, and the fifth column has the relative errors.

Let S be the sum computed using infinite series and exp(x) be the result from Fortran's intrinsic function. Then, the absolute error
and relative error are defined as follows:

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/exp-2.html (2 of 3)8/5/2006 8:06:26 PM


Computing a Set of Values of EXP(x)

You may find out that the value for X are not -1.0, -0.9, -0.8, ..., 0.0, 0.1, 0.2, ..., 0.9 and 1.0. It contains errors. For example, the
last value should be 1.0 instead of 0.900000155. This is a problem of precision being not high enough. See the KIND attribute in
a later chapter.

Discussion

● For the computation using infinite series, see a previous example for the details.
● Since the data points are Begin, Begin+Step, Begin+2*Step and so on, it is simply a DO-loop as follows:

X = Begin
DO
IF (X > End) EXIT
... compute EXP(X) here ...
X = X + Step
END DO

● Inserting the computation part into the place "... computing EXP(X) here ..." gives the program shown above.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/exp-2.html (3 of 3)8/5/2006 8:06:26 PM


Armstrong Numbers

Armstrong Numbers

Problem Statement

An Armstrong number of three digits is an integer such that the sum of the cubes of its digits is equal to the number itself.
For example, 371 is an Armstrong number since 3**3 + 7**3 + 1**3 = 371.

Write a program to find all Armstrong number in the range of 0 and 999.

Solution

! ---------------------------------------------------------------
! This program computes all Armstrong numbers in the range of
! 0 and 999. An Armstrong number is a number such that the sum
! of its digits raised to the third power is equal to the number
! itself. For example, 371 is an Armstrong number, since
! 3**3 + 7**3 + 1**3 = 371.
! ---------------------------------------------------------------

PROGRAM ArmstrongNumber
IMPLICIT NONE

INTEGER :: a, b, c ! the three digits


INTEGER :: abc, a3b3c3 ! the number and its cubic sum
INTEGER :: Count ! a counter

Count = 0
DO a = 0, 9 ! for the left most digit
DO b = 0, 9 ! for the middle digit
DO c = 0, 9 ! for the right most digit
abc = a*100 + b*10 + c ! the number
a3b3c3 = a**3 + b**3 + c**3 ! the sum of cubes
IF (abc == a3b3c3) THEN ! if they are equal
Count = Count + 1 ! count and display it
WRITE(*,*) 'Armstrong number ', Count, ': ', abc
END IF
END DO
END DO
END DO

END PROGRAM ArmstrongNumber

Click here to download this program.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/arms.html (1 of 2)8/5/2006 8:06:28 PM


Armstrong Numbers

Program Input and Output

The following is the output from the above program. Thus, there are six Armstrong numbers in the range of 0 and 999.

Armstrong number 1: 0
Armstrong number 2: 1
Armstrong number 3: 153
Armstrong number 4: 370
Armstrong number 5: 371
Armstrong number 6: 407

Discussion

● Three-digit numbers are 000, 001, 002, ..., 009, 010, 011, ..., 019, 020, 021, 022, ..., 099, 100, 101, 102, ..., 109,
110, ... 990, 991, ..., 999. As you can see the right-most digits changes faster than the middle one, which in turn is
faster than the left-most one. As the left-most and the middle digits are fixed to 0 and 0, the right-most digit changes
from 0 to 9. Then, the middle one is increased from 0 to 1. In other words, whenever the right-most digit completes a
0 to 9 cycle, the middle digit is increased by one and the right-most digit restart another 0 to 9 cycle. By the same
token, whenever the middle digit completes a 0 to 9 cycle, the left-most digit is increased by 1 and the middle digit
restarts another 0 to 9 cycle.

Therefore, if a, b and c are the left-most, the middle and the right-most digits, the above discussion is formalized
with the following three nested DO-loops:

DO a = 0, 9
DO b = 0, 9
DO c = 0, 9
... the number is abc .....
END DO
END DO
END DO

● Now, in the inner most DO, the number in hand is abc, where a, b and c are the left-most, middle and the right-most
digits. The number itself is of course a*100 + b*10 + c. The sum of the cubes of the digits is a**3 + b**3 + c**3. In
the program, these two are stored in abc and a3b3c3, respectively.
● Finally, if abc and a3b3c3 are equal, we have found an Armstrong number. We can use abc or a3b3c3

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/arms.html (2 of 2)8/5/2006 8:06:28 PM


Finding All Prime Numbers in the Range of 2 and N

Finding All Prime Numbers in the Range of 2 and N

Problem Statement

In a previous example, we have discussed how to determine if a positive integer is a prime number. In this one, we shall find all
prime numbers in the range of 2 and N, where N is an input integer.

Write a program to read a value of N, make sure that the value of N is greater than or equal to 2, and display all prime numbers
in the range of 2 and N. In case the value of N is less than 2, your program should keep asking the user to try again until a value
that is greater than or equal to 2 is read.

Solution

! ---------------------------------------------------------------
! This program finds all prime numbers in the range of 2 and an
! input integer.
! ---------------------------------------------------------------

PROGRAM Primes
IMPLICIT NONE

INTEGER :: Range, Number, Divisor, Count

WRITE(*,*) 'What is the range ? '


DO ! keep trying to read a good input
READ(*,*) Range ! ask for an input integer
IF (Range >= 2) EXIT ! if it is GOOD, exit
WRITE(*,*) 'The range value must be >= 2. Your input = ', Range
WRITE(*,*) 'Please try again:' ! otherwise, bug the user
END DO

Count = 1 ! input is correct. start counting


WRITE(*,*) ! since 2 is a prime
WRITE(*,*) 'Prime number #', Count, ': ', 2
DO Number = 3, Range, 2 ! try all odd numbers 3, 5, 7, ...

Divisor = 3 ! divisor starts with 3


DO
IF (Divisor*Divisor > Number .OR. MOD(Number,Divisor) == 0) EXIT
Divisor = Divisor + 2 ! if does not evenly divide, next odd
END DO

IF (Divisor*Divisor > Number) THEN ! are all divisor exhausted?


Count = Count + 1 ! yes, this Number is a prime
WRITE(*,*) 'Prime number #', Count, ': ', Number
END IF
END DO

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/prime-2.html (1 of 3)8/5/2006 8:06:33 PM


Finding All Prime Numbers in the Range of 2 and N

WRITE(*,*)
WRITE(*,*) 'There are ', Count, ' primes in the range of 2 and ', Range

END PROGRAM Primes

Click here to download this program.

Program Input and Output

● The following shows an interaction between the user and program. First, the users type in -10, which is less than 2. This
program displays the input value and a message asking the user to try again. The user then types in 0, which is still less
than 2, causing the same message to occur. The users types in 1 and the same message appears. Finally, after the user
types in 5, the program reports that there are three prime numbers in the range of 2 and 5, namely: 2, 3, and 5.

What is the range ?


-10
The range value must be >= 2. Your input = -10
Please try again:
0
The range value must be >= 2. Your input = 0
Please try again:
1
The range value must be >= 2. Your input = 1
Please try again:
5

Prime number #1: 2


Prime number #2: 3
Prime number #3: 5

There are 3 primes in the range of 2 and 5

● The following is generated with input 100. There are 25 prime numbers in the range of 2 and 100.

What is the range ?


100

Prime number #1: 2


Prime number #2: 3
Prime number #3: 5
Prime number #4: 7
Prime number #5: 11
Prime number #6: 13
Prime number #7: 17
Prime number #8: 19
Prime number #9: 23
Prime number #10: 29
Prime number #11: 31
Prime number #12: 37

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/prime-2.html (2 of 3)8/5/2006 8:06:33 PM


Finding All Prime Numbers in the Range of 2 and N

Prime number #13: 41


Prime number #14: 43
Prime number #15: 47
Prime number #16: 53
Prime number #17: 59
Prime number #18: 61
Prime number #19: 67
Prime number #20: 71
Prime number #21: 73
Prime number #22: 79
Prime number #23: 83
Prime number #24: 89
Prime number #25: 97

There are 25 primes in the range of 2 and 100

Discussion

● We shall use part of the program shown in a previous example for checking if an integer is a prime number. Please refer
to that example for the details.
● How do we write a bullet-proof program so that the values for N and Range in the program are always correct? Here is
the way our program uses:

WRITE(*,*) 'What is the range ? '


DO
READ(*,*) Range
IF (Range >= 2) EXIT
... incorrect input here ...
END DO

It first asks for a number. The actual READis in the DO-loop. After reading in a value for Range, this value is checked
to see if it is greater than or equal to 2. If it is, EXITand find prime numbers, since we have read in a good input.
Otherwise, the input is incorrect and the program shows a message and loops back to read a new one.
● After reading in a correct value for Range, we can start prime number searching. Since Range is larger than or equal to
2, 2 must be included since it is a prime number.
● All the other prime numbers are odd numbers. As a result, we only try to determine if a number in the list of 3, 5, 7, 9,
11, ...., up to Range, is a prime number. This is, of course, the job of a DO-loop:

DO Number = 3, Range, 2
... determine if Number is a prime number ...
... if Number is a prime number, display it ...
END DO

● The segment in the previous example can be used to replace "...determine if Number is a prime number..." and the final
program is the one shown above.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/prime-2.html (3 of 3)8/5/2006 8:06:33 PM


Finding All Prime Factors of a Positive Integer

Finding All Prime Factors of a Positive Integer

Problem Statement

As we have learned in high school, any positive integer can be factorized into prime factors. For example, 586390350 can be
factorized as follows:

Thus, 586390350 has factors 2, 3, 5, 5,, 7, 7, 13, 17, 19 and 19. Note that all factors are prime numbers.

Write a program that reads in an integer greater than or equal to 2 and finds all of its prime factors.

This problem is a little more difficult than the others and may require longer time to understand its logic.

Solution

! ---------------------------------------------------------------
! This program determines all prime factors of an n integer >= 2.
! It first removes all factors of 2. Then, removes all factors
! of 3, 5, 7, and so on. All factors must be prime numbers since
! when a factor is tried all of whose non-prime factors have
! already been removed.
! ---------------------------------------------------------------

PROGRAM Factorize
IMPLICIT NONE

INTEGER :: Input
INTEGER :: Divisor
INTEGER :: Count

WRITE(*,*) 'This program factorizes any integer >= 2 --> '


READ(*,*) Input

Count = 0
DO ! here, we try to remove all factors of 2
IF (MOD(Input,2) /= 0 .OR. Input == 1) EXIT
Count = Count + 1 ! increase count
WRITE(*,*) 'Factor # ', Count, ': ', 2
Input = Input / 2 ! remove this factor from Input
END DO

Divisor = 3 ! now we only worry about odd factors


DO ! 3, 5, 7, .... will be tried

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/factor.html (1 of 4)8/5/2006 8:06:38 PM


Finding All Prime Factors of a Positive Integer

IF (Divisor > Input) EXIT ! if a factor is too large, exit and done
DO ! try this factor repeatedly
IF (MOD(Input,Divisor) /= 0 .OR. Input == 1) EXIT
Count = Count + 1
WRITE(*,*) 'Factor # ', Count, ': ', Divisor
Input = Input / Divisor ! remove this factor from Input
END DO
Divisor = Divisor + 2 ! move to next odd number
END DO

END PROGRAM Factorize

Click here to download this program.

Program Input and Output

● If the input is 100, the output consists of four factors 2, 2, 5 and 5.

This program factorizes any integer >= 2 -->


100

Factor # 1: 2
Factor # 2: 2
Factor # 3: 5
Factor # 4: 5

● If the input is 16, the output consists of four factors 2, 2, 2 and 2.

This program factorizes any integer >= 2 -->


16

Factor # 1: 2
Factor # 2: 2
Factor # 3: 2
Factor # 4: 2

● If the input is 53, since it is a prime number, the output has only one factor: 53 itself.

This program factorizes any integer >= 2 -->


53

Factor # 1: 53

● If the input value is 586390350, the output consists of 10 factors 2, 3, 5, 5, 7, 7, 13, 17, 19 and 19.

This program factorizes any integer >= 2 -->


586390350

Factor # 1: 2
Factor # 2: 3

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/factor.html (2 of 4)8/5/2006 8:06:38 PM


Finding All Prime Factors of a Positive Integer

Factor # 3: 5
Factor # 4: 5
Factor # 5: 7
Factor # 6: 7
Factor # 7: 13
Factor # 8: 17
Factor # 9: 19
Factor # 10: 19

Discussion

● How to remove a factor from a given number? I believe you have learned it in high school. Let the given number be n
and we know x is a factor of n. Then, we just keep dividing n by x until the quotient is 1 or x cannot evenly divide n.

For example, 3 is a factor of 72. The first division yields a quotient 24=72/3. The second division yields a quotient
8=24/3. Thus, the original number 72 has two factors of 3.

If n and x are both 53, then the first division yields a quotient 1=53/53. Since the quotient is 1, no more division is
necessary and 53 has a factor 53!
● So, how to convert the above idea to a program? Let us use Input and Divisor for n and x, respectively. The following
DO-loop will do the job:

DO
IF (MOD(Input,Divisor) /= 0 .OR. Input == 1) EXIT
... since MOD(Input,Divisor)=0 here, Divisor is a factor...
Input = Input / Divisor
END DO

In the above, if Divisorcannot evenly divide Inputor Inputis 1, we exit the loop. The former condition states that
Divisoris not a factor of Input, while the latter means Inputis 1 and does not have any other factor.

If both conditions are .FALSE., then Divisor can evenly divide Input and Input is not 1. Therefore, Input is a factor
of Divisor. To remove it, just perform a division and this is the meaning of Input = Input / Divisor.

● Since 2 is the only even prime number, we'd better remove all factors of 2 before starting any other work. Therefore,
letting Divisor to 2 in the above code will remove all factor of 2:

DO
IF (MOD(Input,2) /= 0 .OR. Input == 1) EXIT
... since MOD(Input,2)=0 here, 2 is a factor...
Input = Input / Divisor
END DO

After exiting this loop, we are sure the new value of Inputwill have no factors of 2. Then, we can try all odd numbers to
see some of them could be factors.
● To try odd numbers, it is simply the following:

Divisor = 3
DO

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/factor.html (3 of 4)8/5/2006 8:06:38 PM


Finding All Prime Factors of a Positive Integer

IF (Divisor > Input) EXIT


...remove all factors of Divisor...
Divisor = Divisor + 2
END DO

● Putting everything together, it is the program shown above.


● Why the factors found are prime numbers? A good question, indeed.

It is not difficult to answer, however. If Input does have a composite factor (a composite number is the product of
several prime numbers), say x = a*b, where a is a prime number. Then, before the program can test if x is a factor, a
has been tested since a < x, and the factor a is removed. Consequently, only a possible factor b remains. In other words,
composite number x is never tested and the program will not report any composite factors.
● Let us factorize 586390350 as an example:
1. Factors of 2 are removed first. Removing the first factor of 2 yields 293195175=586390350/2.
2. Since 293195175 is not even, it has no more factors of 2. So, we shall try all odd numbers: 3, 5, 7, 9, 11, ...
3. Removing a factor of 3 yields 97731725=293195175/3.
4. Since 97731725 has no factors of 3, try 5.
5. Removing a factor of 5 yields 19546345=97731725/5.
6. Removing a factor of 5 a second time yields 3909269=19546345/5.
7. Since 3909269 has no factors of 5, try 7.
8. Removing a factor of 7 yields 558467=3909269/7.
9. Removing a second factor of 7 yields 79781=558467/7.
10. Since 79781 has no factors of 7, try 9.
11. Since 79781 has no factors of 9, try 11.
12. Since 79781 has no factors of 11, try 13.
13. Removing a factor of 13 yields 6137=79781/13.
14. Since 6137 has no factor of 13, try 15.
15. Since 6137 has no factor of 15, try 17.
16. Removing a factor of 17 yields 361=6137/17.
17. Since 361 has no factor of 17, try 19.
18. Removing a factor of 19 yields 19=361/19.
19. Removing a second factor of 19 yields 1=19/19.
20. Since the quotient is already 1, stop and all factors have been reported.

You might feel this is not a very efficient method since testing if 9 and 15 are factors are redundant. Yes, you are right;
but, this is already a reasonable complicated program for CS110 and CS201. You could learn more efficient
factorization algorithms in other computer science and/or mathematics courses, since this is an extremely important
topic.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/factor.html (4 of 4)8/5/2006 8:06:38 PM


Handling End-of-File: the READ Statement Revisited

Handling End-of-File: the READ Statement Revisited

In many situations, you really do not know the number of items in the input. It could be so large to be counted accurately.
Consequently, we need a method to handle this type of input. In fact, you have encountered such a technique in
Programming Assignment 1 in which a keyword IOSTAT= was used in a READ statement. The following is its syntax:

INTEGER :: IOstatus

READ(*,*,IOSTAT=IOstatus) var1, var2, ..., varn

The third component of the above READ is IOSTAT= followed by an INTEGER variable. The meaning of this new form
of READ is simple:

After executing the above READ statement, the Fortran compiler will put an integer value into the integer variable
following IOSTAT=, IOstatus above. Based on the value of IOstatus, we have three different situations:

1. If the value of IOstatus is zero, the previous READ was executed flawlessly and all variables have received their
input values. This is the normal case.
2. If the value of IOstatus is positive, the previous READ has encountered some problem. In general, without knowing
the system dependent information, it is impossible to determine what the problem was. However, if hardware and I/
O devices are working, a commonly seen problem would be illegal data. For example, supplying a real number to an
integer variable. If IOstatus is positive, you cannot trust the values of the variables in the READ statement; they
could all contain garbage values, or some of them are fine while the others are garbage.
3. If the value of IOstatus is negative, it means the end of the input has reached. Under this circumstance, some or all
of the variables in the READ may not receive input values.

What is the end of file? How do we generate it? If you prepare your input using a file, when you save it, the system will
generate a special mark, called end-of-file mark, at the end of that file. Therefore, when you read the file and encounter that
special end-of-file mark, the system would know there is no input data after this mark. If you try to read passing this mark,
it is considered as an error.

If you prepare the input using keyboard, hiting the Ctrl-D key would generate the end-of-mark under UNIX. Once you hit
Ctrl-D, the system would consider your input stop at there. If your program tries to read passing this point, this is an error.

However, with IOSTAT=, you can catch this end-of-file mark and do something about it. A commonly seen application is
that let the program to count the number of data items as will be shown in examples below.

Examples

● In the following code, the DO-loop keeps reading in three integer values into variables a, b and c. After executing a
READ, if Reason is greater than zero, something was wrong in the input; if Reason is less than zero, end-of-file has
reached. Only if Reason is zero, one can start normal processing.

INTEGER :: Reason
INTEGER :: a, b, c

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/iostatus.html (1 of 2)8/5/2006 8:06:40 PM


Handling End-of-File: the READ Statement Revisited

DO
READ(*,*,IOSTAT=Reason) a, b, c
IF (Reason > 0) THEN
... something wrong ...
ELSE IF (Reason < 0) THEN
... end of file reached ...
ELSE
... do normal stuff ...
END IF
END DO

● The following code keeps reading an integer at a time and adds them to a variable sum. If io is greater than zero, it
displays 'Check input. Something was wrong'; if io is less than zero, it displays the value of sum. Note that both
cases EXIT the DO-loop since continuing the loop execution makes no sense. Otherwise, the value of x is
meaningful and is added to sum.

INTEGER :: io, x, sum

sum = 0
DO
READ(*,*,IOSTAT=io) x
IF (io > 0) THEN
WRITE(*,*) 'Check input. Something was wrong'
EXIT
ELSE IF (io < 0) THEN
WRITE(*,*) 'The total is ', sum
EXIT
ELSE
sum = sum + x
END IF
END DO

Now if the input is

1
3
4

the above code should display 8 (=1+3+4). If the input is

1
@
3

since @ is not a legal integer, the second time the READis executed, iowould receive a positive number and the
above program exits the DO-loop.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/iostatus.html (2 of 2)8/5/2006 8:06:40 PM


Computing Arithmetic, Geometric and Harmonic Means: Revisited

Computing Arithmetic, Geometric and Harmonic Means:


Revisited

Problem Statement

The arithmetic mean (i.e., average), geometric mean and harmonic mean of a set of n numbers x1, x2, ..., xn is defined as
follows:

Since computing geometric mean requires taking root, it is further required that all input data values must be positive. As a
result, this program must be able to ignore those non-positive items. However, this may cause all input items ignored.
Therefore, before computing the means, this program should have one more check to see if there are valid items.

Unlike a previous example, this program does not know the number of input items and must handle incorrect input data and
ignore them.

Solution

! -----------------------------------------------------------
! This program can read an unknown number of input until the
! end of file is reached. It calculates the arithmetic,
! geometric, and harmonic means of these numbers.
!
! This program uses IOSTAT= to detect the following two
! conditions:
! (1) if the input contains illegal symbols (not numbers)
! (2) if the end of input has reached
! -----------------------------------------------------------

PROGRAM ComputingMeans
IMPLICIT NONE

REAL :: X
REAL :: Sum, Product, InverseSum
REAL :: Arithmetic, Geometric, Harmonic
INTEGER :: Count, TotalValid
INTEGER :: IO ! this is new variable

Sum = 0.0

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/means-4.html (1 of 4)8/5/2006 8:06:42 PM


Computing Arithmetic, Geometric and Harmonic Means: Revisited

Product = 1.0
InverseSum = 0.0
TotalValid = 0
Count = 0

DO
READ(*,*,IOSTAT=IO) X ! read in data
IF (IO < 0) EXIT ! IO < 0 means end-of-file reached
Count = Count + 1 ! otherwise, there are data in input
IF (IO > 0) THEN ! IO > 0 means something wrong
WRITE(*,*) 'ERROR: something wrong in your input'
WRITE(*,*) 'Try again please'
ELSE ! IO = 0 means everything is normal
WRITE(*,*) 'Input item ', Count, ' --> ', X
IF (X <= 0.0) THEN
WRITE(*,*) 'Input <= 0. Ignored'
ELSE
TotalValid = TotalValid + 1
Sum = Sum + X
Product = Product * X
InverseSum = InverseSum + 1.0/X
END IF
END IF
END DO

WRITE(*,*)
IF (TotalValid > 0) THEN
Arithmetic = Sum / TotalValid
Geometric = Product**(1.0/TotalValid)
Harmonic = TotalValid / InverseSum

WRITE(*,*) '# of items read --> ', Count


WRITE(*,*) '# of valid items -> ', TotalValid
WRITE(*,*) 'Arithmetic mean --> ', Arithmetic
WRITE(*,*) 'Geometric mean --> ', Geometric
WRITE(*,*) 'Harmonic mean --> ', Harmonic
ELSE
WRITE(*,*) 'ERROR: none of the input is positive'
END IF

END PROGRAM ComputingMeans

Click here to download this program.

Program Input and Output

The input consists of a number of real values, one on each line. The program will count the number of input data items and
ignore those illegal ones.

● If the input data is

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/means-4.html (2 of 4)8/5/2006 8:06:42 PM


Computing Arithmetic, Geometric and Harmonic Means: Revisited

1.0
2.0
3.0
4.0
5.0
6.0

it will generate the following output. In this input, all data values are positive and none of them is ignored.

Input item 1 --> 1.


Input item 2 --> 2.
Input item 3 --> 3.
Input item 4 --> 4.
Input item 5 --> 5.
Input item 6 --> 6.

# of items read --> 6


# of valid items -> 6
Arithmetic mean --> 3.5
Geometric mean --> 2.99379516
Harmonic mean --> 2.44897938

● The following input contains a few illegal items. The third one is 3.o rather than 3.0. Thus, it is not a legal real value.
The eighth item is #.$, which is not a number at all. Also, the sixth and tenth are non-positive.

1.0
2.0
3.o
4.0
5.0
-1.0
7.0
#.$
9.0
0.0

The output is shown below. It correctly identifies all illegal data input items.

Input item 1 --> 1.


Input item 2 --> 2.
ERROR: something wrong in your input
Try again please
Input item 4 --> 4.
Input item 5 --> 5.
Input item 6 --> -1.
Input <= 0. Ignored
Input item 7 --> 7.
ERROR: something wrong in your input
Try again please
Input item 9 --> 9.
Input item 10 --> 0.E+0
Input <= 0. Ignored

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/means-4.html (3 of 4)8/5/2006 8:06:42 PM


Computing Arithmetic, Geometric and Harmonic Means: Revisited

# of items read --> 10


# of valid items -> 6
Arithmetic mean --> 4.66666651
Geometric mean --> 3.68892741
Harmonic mean --> 2.72236228

Discussion

● The use of IOSTAT= follows closely the examples discussed in Handling End of File: READ Statement Revisited.
● This program uses an INTEGER variable IO to keep track the status of a read.
● If the value of IO is negative, end-of-file reached and the program exists the DO-loop.
● If the value of IO is positive, the previous READ had some problem. A message is displayed and asks the user to try
again. In an interactive environment, this is a good practice.
● If the value of IO is zero, we have a normal situation. Then, the program checks further to see if the input is negative.
This is exactly identical to a previous example and hence its discussion is omitted.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/means-4.html (4 of 4)8/5/2006 8:06:42 PM


The DO-CYCLE Construct and a Programming Example

The DO-CYCLE Construct and a Programming Example

In parallel with the DO-EXIT construct, Fortran has a DO-CYCLE construct as follows:

DO control-info
statements-1
CYCLE
statements-2
END DO

where control-info is empty if the loop is a DO-END DO; otherwise, control-info contains all information that a counting
DO should have.

When the execution of a DO-loop encounters the CYCLE statement, the DO-loop starts next iteration immediately.

This is not a recommended feature. So, if it is possible, do not use it.

Examples

● The following loop only displays 1, 2, 4 and 5. If the value of i is 1, 2, 4 or 5, the execution of the loop enters the
ELSE part and displays the value of i. However, if i is 3, since i == 3 is .TRUE., the CYCLE statement is executed,
which brings back to the beginning of the DO-loop starting the next iteration (i.e., the iteration corresponds to i=4).

INTEGER :: i

DO i = 1, 5
IF (i == 3) THEN
CYCLE
ELSE
WRITE(*,*) i
END IF
END DO

● The following code has a DO-loop for processing the input value stored in Range. At the beginning of the loop, the
value of Range is read in and checked. If the value is less than 2, the CYCLE statement brings the control back to
the beginning of the loop to read a new value for Range. This will continue until a value that is greater than or equal
to 2. Then, the logical expression of the IF-THEN-END IF is .FALSE. and consequently the execution continues
with "... process Range ...".

INTEGER :: Range

DO
WRITE(*,*) 'An integer >= 2 please --> '
READ(*,*) Range
IF (Range < 2) THEN

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/do-cycle.html (1 of 4)8/5/2006 8:06:46 PM


The DO-CYCLE Construct and a Programming Example

WRITE(*,*) 'Input not in the required range'


CYCLE
END IF
... process Range ...
END DO

Please compare this example with the technique used in the second prime number example in which EXIT is used
rather than CYCLE.

A Programming Example
This problem solves a puzzle: RED x FOR = DANGER, where each letter represents a digit and different letters means
different digits. Moreover, R, F and D cannot be zero.

Write a program to find all solutions.

Solution

! ----------------------------------------------------------
! This program solve the following puzzle:
! RED
! x FOR
! -------
! DANGER
! where each distinct letter represents a different digit.
! Moreover, R, F and D cannot be zero.
! ----------------------------------------------------------

PROGRAM Puzzle
IMPLICIT NONE

INTEGER :: R, E, D, F, O, A, N, G ! the digits


INTEGER :: RED, FOR, DANGER ! the constructed values
INTEGER :: Count ! solutions count

WRITE(*,*) 'This program solves the following puzzle:'


WRITE(*,*)
WRITE(*,*) ' RED'
WRITE(*,*) 'x FOR'
WRITE(*,*) '-------'
WRITE(*,*) ' DANGER'
WRITE(*,*)

Count = 0
DO R = 1, 9
DO E = 0, 9
IF (E == R) CYCLE

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/do-cycle.html (2 of 4)8/5/2006 8:06:46 PM


The DO-CYCLE Construct and a Programming Example

DO D = 1, 9
IF (D == R .OR. D == E) CYCLE
DO F = 1, 9
IF (F == R .OR. F == E .OR. F == D) CYCLE
DO O = 0, 9
IF (O == R .OR. O == E .OR. O == D .OR. &
O == F) CYCLE
DO A = 0, 9
IF (A == R .OR. A == E .OR. A == D .OR. &
A == F .OR. A == O) CYCLE
DO N = 0, 9
IF (N == R .OR. N == E .OR. N == D .OR. &
N == F .OR. N == O .OR. N == A) CYCLE
DO G = 0, 9
IF (G == R .OR. G == E .OR. G == D .OR. &
G == F .OR. G == O .OR. G == A .OR. &
G == N) CYCLE
RED = R*100 + E*10 + D
FOR = F*100 + O*10 + R
DANGER = D*100000 + A*10000 + N*1000 + G*100 + E*10 + R
IF (RED * FOR == DANGER) THEN
Count = Count + 1
WRITE(*,*) 'Solution ', Count, ':'
WRITE(*,*) ' RED = ', RED
WRITE(*,*) ' FOR = ', FOR
WRITE(*,*) ' DANGER = ', DANGER
WRITE(*,*)
END IF
END DO
END DO
END DO
END DO
END DO
END DO
END DO
END DO

END PROGRAM Puzzle

Click here to download this program.

Program Output

The following is the output generated by the above program. There are two solutions:

This program solves the following puzzle:

RED
x FOR

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/do-cycle.html (3 of 4)8/5/2006 8:06:46 PM


The DO-CYCLE Construct and a Programming Example

-------
DANGER

Solution 1:
RED = 321
FOR = 563
DANGER = 180723

Solution 2:
RED = 481
FOR = 364
DANGER = 175084

Discussion

● This program uses a brute-force method. That is, it searches all possibilities.
● Since there are eight digits, R, E, D, F, O, A, N and G, each of which runs from 0 to 9 except for R, F and D which
runs from 1 to 9, we need eight nested DO-loops.
● Since different letters represent different digits, at the very beginning of a DO-loop, we must make sure the value of
its control variable is different from the values of all previous loops.

DO R = 1, 9
DO E = 0, 9
IF (E == R) CYCLE
DO D = 1, 9
IF (D == R .OR. D == E) CYCLE
... other loops ...
END DO
END DO
END DO

The above only shows three loops for R, E and D. At the beginning of the E loop, the value of E is checked to see if it
is equal to the value of R. If they are equal, the CYCLE brings the control to the next iteration. Similarly, at the
beginning of the D loop, the value of D is compared against the values of E and R. If they are equal, CYCLE causes
the start of the next iteration. Note that D runs from 1 to 9.
● In the inner-most loop, the value of RED, FOR and DANGER are computed and compared. If RED*FOR is equal
to DANGER, a solution is found and its values are displayed.

RED = R*100 + E*10 + D


FOR = F*100 + O*10 + R
DANGER = D*100000 + A*10000 + N*1000 + G*100 + E*10 + R
IF (RED * FOR == DANGER) THEN
... display READ, FOR and DANGER ...
END IF

● The concept of this program, except for the use of CYCLE, is similar to that of finding all three-digit Armstrong
Numbers. Please compare these two programs.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/do-cycle.html (4 of 4)8/5/2006 8:06:46 PM


Functions and Modules

Functions and Modules

Select the topics you wish to review:

Functions and Modules


Designing Functions
Functions Examples
Common Problems
Using Functions
Argument Association
Where Do My Functions Go?
Scope Rules
Programming Examples:
Computing Cubes
Computing Means - Revisited
Cm and Inch Conversion
Heron'a Formula for Computing Triangle Area - Revisited
Computing the Combinatorial Coefficient
Computing Square Roots with Newton's Method
Designing a Greatest Common Divisor Function
Finding All Prime Numbers in the Range of 2 and N - Revisited
The Bisection (Bozano) Equation Solver
A Brief Introduction to Modules
What is a Module?
How to Use a Module?
Compile Programs with Modules
Programming Example 1: Factorial and Combinatorial Coefficient
Programming Example 2: Trigonometric Functions Using Degree
A Little Privacy - PUBLIC/PRIVATE
External Functions and Interface Blocks
Interface Blocks
Programming Example 1: Cm and Inch Conversion
Programming Example 2: Heron'a Formula for Computing Triangle Area
Download my course overheads

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/funct-module.html8/5/2006 8:09:53 PM
Designing Functions

Designing Functions

Syntax

In addition to intrinsic functions, Fortran allows you to design your own functions. A Fortran function, or more precisely, a
Fortran function subprogram, has the following syntax:

type FUNCTION function-name (arg1, arg2, ..., argn)


IMPLICIT NONE
[specification part]
[execution part]
[subprogram part]
END FUNCTION function-name

Here are some elaborations of the above syntax:

● The first line of a function starts with the keyword FUNCTION. Before FUNCTION, the type gives the type of the
function value (i.e., INTEGER, REAL, LOGICAL and CHARACTER) and after FUNCTION is the name you
assign to that function.
● Following the function-name, there is a pair of parenthesis in which a number of arguments arg1, arg2, ..., argn are
separated with commas. These arguments are referred to as formal arguments. Formal arguments must be variable
names and cannot be expressions. Here are a examples:
1. The following is a function called Factorial. It takes only one formal argument n and returns an INTEGER
as its function value.

INTEGER FUNCTION Factorial(n)

2. The following is a function called TestSomething. It takes three formal arguments a, b and c, and returns a
LOGICAL value (i.e., .TRUE. or .FALSE.) as its function value.

LOGICAL FUNCTION TestSomething(a, b, c)

● A function must be ended with END FUNCTION followed by the name of that function.
● Between FUNCTION and END FUNCTION, there are the IMPLICIT NONE, specification part, execution part
and subprogram part. These are exactly identical to that of a PROGRAM.

If a function does not need any formal argument, it can be written as

type FUNCTION function-name ()


IMPLICIT NONE
[specification part]
[execution part]
[subprogram part]
END FUNCTION function-name

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/funct.html (1 of 2)8/5/2006 8:09:57 PM


Designing Functions

where arg1, arg2, ..., argn are left out. But, the pait of parenthesis must be there.

Semantics

The meaning of a function is very simple:

● A function is a self-contained unit that receives some "input" from the outside world via its formal arguments, does
some computations, and then returns the result with the name of the function.
● Thus, since the function returns its result via the name of the function, somewhere in the function there must exist
one or more assignment statements like the following:

function-name = expression

where the result of expressionis stored to the name of the function.

However, the name of the function cannot appear in the right-hand side of any expression. That is, the name of
the function, used as a variable name, can only appear in the left-hand side of an expression. This is an artificial
restriction in this course only.

● A function receives its input values from formal arguments, does computations, and saves the result in its name.
When the control of execution reaches END FUNCTION, the value stored in the name of the function is returned as
the function value.
● To tell the function about the types of its formal arguments, all arguments must be declared with a new attribute
INTENT(IN). The meaning of INTENT(IN) indicates that the function will only take the value from the formal
argument and must not change its content.
● Any statements that can be used in PROGRAM can also be used in a FUNCTION.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/funct.html (2 of 2)8/5/2006 8:09:57 PM


Function Examples

Functions Examples

Here are a few examples of functions:

● The following function has a name Sum and three formal arguments a, b and c. It returns an INTEGER function
value. The INTEGER, INTENT(IN) part indicates that the function takes its input value from its three formal
argument. Then, the function uses the value of these formal arguments to compute the sum and stores in Sum, the
name of the function. Since the next statement is END FUNCTION, the function returns the value stored in Sum.

INTEGER FUNCTION Sum(a, b, c)


IMPLICIT NONE

INTEGER, INTENT(IN) :: a, b, c

Sum = a + b + c
END FUNCTION Sum

If the value supplied to a, band care 3, 5, and -2, respectively, Sumwill receive 6 (=3+5+(-2)) and the function
returns 6.
● The following function has a name Positive with a REAL formal argument. If the argument is positive, the function
returns .TRUE.; otherwise, the function returns .FALSE.

LOGICAL FUNCTION Positive(a)


IMPLICIT NONE

REAL, INTENT(IN) :: a

IF (a > 0.0) THEN


Positive = .TRUE.
ELSE
Positive = .FALSE.
END IF
END FUNCTION Positive

The above function can be made much shorter by using LOGICALassignment. In the following, if a > 0.0is true, .
TRUE.is stored to Positive; otherwise, Positivereceives .FALSE.

LOGICAL FUNCTION Positive(a)


IMPLICIT NONE

REAL, INTENT(IN) :: a

Positive = a > 0.0


END FUNCTION Positive

● The following function, LargerRoot, takes three REAL formal arguments and returns a REAL function value. It

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/f-examp.html (1 of 3)8/5/2006 8:09:59 PM


Function Examples

returns the larger root of a quadratic equation ax2 + bx + c = 0.

REAL FUNCTION LargerRoot(a, b, c)


IMPLICIT NONE

REAL, INTENT(IN) :: a
REAL, INTENT(IN) :: b
REAL, INTENT(IN) :: c
REAL :: d, r1, r2

d
= SQRT(b*b - 4.0*a*c)
r1
= (-b + d) / (2.0*a)
r2
= (-b - d) / (2.0*a)
IF
(r1 >= r2) THEN
LargerRoot = r1
ELSE
LargerRoot = r2
END IF
END FUNCTION LargerRoot

The above example shows that you can declare other variables such as d, r1and r2if they are needed.
● The following function, Factorial(), has only one INTEGER formal argument n >= 0, and computes and returns the
factorial of n, n!.

INTEGER FUNCTION Factorial(n)


IMPLICIT NONE

INTEGER, INTENT(IN) :: n
INTEGER :: i, Ans

Ans = 1
DO i = 1, n
Ans = Ans * i
END DO
Factorial = Ans
END FUNCTION

Note that the function name Factorialis not used in any computation. Instead, a new INTEGERvariable is used for
computing n!. The final value of Ansis stored to Factorialbefore leaving the function.

If Factorial is involved in computation like the following:

INTEGER FUNCTION Factorial(n)


IMPLICIT NONE

INTEGER, INTENT(IN) :: n
INTEGER :: i

Factorial = 1
DO i = 1, n

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/f-examp.html (2 of 3)8/5/2006 8:09:59 PM


Function Examples

Factorial = Factorial * i
END DO
END FUNCTION

then there is a mistake although the above program looks normal. The reason is that the function name cannot appear
in the right-hand sidein any expression of that function.
● The following function GetNumber() does not have any formal arguments and returns an INTEGER function
value. This function has a DO-loop which keeps asking the user to input a positive number. The input is read into
the function name. If this value is positive, then EXIT and the function returns the value in GetNumber. Otherwise,
the loop goes back and asks the user again for a new input value.

REAL FUNCTION GetNumber()


IMPLICIT NONE

DO
WRITE(*,*) 'A positive real number --> '
READ(*,*) GetNumber
IF (GetNumber > 0.0) EXIT
WRITE(*,*) 'ERROR. Please try again.'
END DO
WRITE(*,*)
END FUNCTION GetNumber

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/f-examp.html (3 of 3)8/5/2006 8:09:59 PM


Common Problems

Common Problems

● Forget the type of a FUNCTION.

FUNCTION DoSomething(a, b)
IMPLICIT NONE

INTEGER, INTENT(IN) :: a, b

DoSomthing = SQRT(a*a + b*b)


END FUNCTION DoSomthing

If there is no type, you will not be able to determine if the returned value is an INTEGER, a REALor something
else.
● Forget INTENT(IN).

REAL FUNCTION DoSomething(a, b)


IMPLICIT NONE

INTEGER :: a, b

DoSomthing = SQRT(a*a + b*b)


END FUNCTION DoSomthing

Actually, this is notan error. But, without INTENT(IN), our Fortran compiler will not be able to check many
potential errors for you.
● Change the value of a formal argument declared with INTENT(IN).

REAL FUNCTION DoSomething(a, b)


IMPLICIT NONE

INTEGER, INTENT(IN) :: a, b

IF (a > b) THEN
a = a - b
ELSE
a = a + b
END IF
DoSomthing = SQRT(a*a + b*b)
END FUNCTION DoSomthing

Since formal argument ais declared with INTENT(IN), its value cannot be changed.
● Forget to store a value to the function name.

REAL FUNCTION DoSomething(a, b)


IMPLICIT NONE

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/c-err.html (1 of 2)8/5/2006 8:10:01 PM


Common Problems

INTEGER, INTENT(IN) :: a, b
INTEGER :: c

c = SQRT(a*a + b*b)
END FUNCTION DoSomthing

When the execution of this function reaches END FUNCTION, it returns the value stored in DoSomething.
However, in the above, since there is no value ever stored in DoSmething, the returned value could be anything (i.e.,
a garbage value).
● Function name is used in the right-hand side of an expression.

REAL FUNCTION DoSomething(a, b)


IMPLICIT NONE

INTEGER, INTENT(IN) :: a, b

DoSomething = a*a + b*b


DoSomething = SQRT(DoSomething)
END FUNCTION DoSomthing

In the above, function name DoSomethingappears in the right-hand side of the second expression. This is a mistake.
Only a special type of functions, RECURSIVEfunctions, could have their names in the right-hand side of
expressions.
● Only the most recent value stored in the function name will be returned..

REAL FUNCTION DoSomething(a, b)


IMPLICIT NONE

INTEGER, INTENT(IN) :: a, b

DoSomething = a*a + b*b


DoSomething = SQRT(a*a - b*b)
END FUNCTION DoSomthing

In the above, the value of SQRT(a*a-b*b)rather than the value of a*a + b*bis returned. In fact, this is obvious.
Since the name of a function can be considered as a special variable name, the second assignment overwrites the
previous value.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/c-err.html (2 of 2)8/5/2006 8:10:01 PM


Using Functions

Using Functions

The way of using a user-defined function is exactly identical to that of using Fortran intrinsic functions. One can use a
function in an expression and in a WRITE. Suppose we have the following function:

REAL FUNCTION Average(x, y, z)


IMPLICIT NONE

REAL, INTENT(IN) :: x, y, z

Average = (x + y + z) / 3.0
END FUNCTION Average

This function takes three REAL formal arguments and returns their average.

To use this function, one needs to supply values to the formal arguments. For example, one could write the following:

..... = ..... + Average(1.0, 2.0, 3.0) * .....

The above expression involves the use of function Average. Since this function has three formal arguments, three values
must be presented to the function. Here, the values are 1.0, 2.0 and 3.0 and the returned value is the average of these three
numbers (i.e., 2.0). The values or expressions used to invoke a function are referred to as actual arguments.

Please keep the following important rules in mind:

● The number of formal arguments and actual arguments must be equal.

..... = ... + Average(1.0, 2.0, 3.0, 4.0) * ....


..... = ... - Average(3.0, 6.0) + .....

The first line has more actual arguments than the number of formal arguments, and the second line has less actual
arguments than the number of formal arguments.
● The type of the corresponding actual and formal arguments must be identical.

WRITE(*,*) Average(1, 2.5, 3.7)

In the above example, the first actual argument is an INTEGERwhich doe not match with the type of the first
formal argument. Thus, it is incorrect.
● The actual arguments can be constants, variables and even expressions.

REAL :: a = 1.0, b = 2.0, c = 3.0

..... = ... + Average(1.0, 2.0, 3.0) + .....


..... = ... + Average(a, b, c) + .....
..... = ... + Average(a+b, b*c, (b+c)/a) + .....

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/use.html (1 of 2)8/5/2006 8:10:03 PM


Using Functions

In the above, the first line shows the use of constants as actual arguments. The second line uses variables, while the
third uses expression. In the third line, the result of evaluating a+b, b*cand (b+c)/awill be supplied to the three
formal arguments of function Average().

Please continue with the next page on argument association

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/use.html (2 of 2)8/5/2006 8:10:03 PM


Argument Association

Argument Association

When using a function, the values of actual arguments are passed to their corresponding formal arguments. There are some
important rules:

● If an actual argument is an expression, it is evaluated and the result is saved into a temporary location. Then, the
value in this temporary location is passed.
● If an actual argument is a constant, it is considered as an expression. Therefore, its value is saved to a temporary
location and then passed.
● If an actual argument is a variable, its value is taken and passed to the corresponding formal argument.
● If an actual argument is a variable enclosed in a pair of parenthesis like (A), then this is an expression and its value is
evaluated and saved to a temporary location. Then, this value (in the temporary location) is passed.
● For a formal argument declared with INTENT(IN), any attempt to change its value in the function will cause a
compiler error. The meaning of INTENT(IN) is that this formal argument only receives a value from its
corresponding actual argument and its value cannot be changed.
● Based on the previous point, if a formal argument is declared without using INTENT(IN), its value can be changed.
For writing functions, this is not a good practice and consequently all formal arguments should be declared with
INTENT(IN).

Example

We shall use the following function to illustrate the above rules. Function Small() takes three formal arguments x, y and z
and returns the value of the smallest.

INTEGER :: a, b, c INTEGER FUNCTION Small(x, y, z)


IMPLICIT NONE
a = 10 INTEGER, INTENT(IN) :: x, y, z
b = 5
c = 13 IF (x <= y .AND. x <= z) THEN
WRITE(*,*) Small(a,b,c) Small = x
WRITE(*,*) Small(a+b,b+c,c) ELSE IF (y <= x .AND. y <= z) THEN
WRITE(*,*) Small(1, 5, 3) Small = y
WRITE(*,*) Small((a),(b),(c)) ELSE
Small = z
END IF
END FUNCTION Small

In the first WRITE, all three arguments are variable and their values are sent to the corresponding formal argument.
Therefore, x, y and z in function Small() receives 10, 5 and 13, respectively. The following diagram illustrate this
association:

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/association.html (1 of 3)8/5/2006 8:10:08 PM


Argument Association

In the second WRITE, the first and second arguments are expression a+b, b+c. Thus, they are evaluated yielding 15 and
18. These two values are saved in two temporary locations and passed to function Small() along with variable c. Thus, x, y
and z receive 15, 18 and 13 respectively. This is illustrated as follows. In the figure, squares drawn with dotted lines are
temperary locations that are created for passing the values of arguments.

In the third WRITE, since all actual arguments are constants, their values are "evaluated" to temporary locations and then
sent to x, y and z.

In the fourth WRITE, since all three actual arguments are expressions, they are evaluated and stored in temporary
locations. Then, these values are passed to x, y and z.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/association.html (2 of 3)8/5/2006 8:10:08 PM


Argument Association

Thus, x, y and z receive 10, 5 and 13, respectively.

Note that while the formal arguments of function Small() receive the same values using the first and the fourth lines,
the argument associations are totally different. The first line has the values in variables passed directly and the the
fourth line evaluates the expressions into temporary locations whose values are passed. This way of argument
association does not have impact on functions (since you must use INTENT(IN)), it will play an important role in
subroutine subprograms.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/association.html (3 of 3)8/5/2006 8:10:08 PM


Where Do My Functions Go?

Where Do My Functions Go?

Now you have your functions. Where do they go? There are two places for you to add these functions in. They are either
internal or external. This page only describes internal functions. See external subprogram for the details of using
external functions.

Long time ago, we mentioned the structure of a Fortran program. From there, we know that the last part of a program is
subprogram part. This is the place for us to put the functions. Here is the syntax:

PROGRAM program-name
IMPLICIT NONE
[specification part]
[execution part]
CONTAINS
[your functions]
END PROGRAM program-name

In the above, following all executable statements, there is the keyword CONTAINS, followed by all of your functions,
followed by END PROGRAM.

From now on, the program is usually referred to as the main program or the main program unit. A program always starts
its execution with the first statement of the main program. When a function is required, the control of execution is
transfered into the corresponding function until the function completes its task and returns a function values. Then, the main
program continues its execution and uses the returned function value for further computation.

Examples

● The following complete program "contains" one function, Average(). The execution
part consists of three statements, a READ, an assignment and a WRITE. These three
statements must be placed before the keyword CONTAINS. Note also that END
PROGRAM must be the last line of your program.

PROGRAM Avg
IMPLICIT NONE
REAL :: a, b, c, Mean

READ(*,*) a, b, c
Mean = Average(a, b, c)
WRITE(*,*) a, b, c, Mean

CONTAINS
REAL FUNCTION Average(a, b, c)
IMPLICIT NONE

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/place.html (1 of 3)8/5/2006 8:10:10 PM


Where Do My Functions Go?

REAL, INTENT(IN) :: a, b, c
Average = (a + b + c) / 3.0
END FUNCTION Average
END PROGRAM Avg

● The following program "contains" two functions Large() and GeoMean(). The order of
these functions are unimportant.

PROGRAM TwoFunctions
IMPLICIT NONE
INTEGER :: a, b, BiggerOne
REAL :: GeometricMean

READ(*,*) a, b
BiggerOne = Large(a,b)
GeometricMean = GeoMean(a,b)
WRITE(*,*) 'Input = ', a, b
WRITE(*,*) 'Larger one = ', BiggerOne
WRITE(*,*) 'Geometric Mean = ', GeometricMean

CONTAINS
INTEGER FUNCTION Large(a, b)
IMPLICIT NONE
INTEGER, INTENT(IN) :: a, b
IF (a >= b) THEN
Large = a
ELSE
Large = b
END IF
END FUNCTION Large

REAL FUNCTION GeoMean(a, b)


IMPLICIT NONE
INTEGER, INTENT(IN) :: a, b
GeoMean = SQRT(REAL(a*b))
END FUNCTION GeoMean
END PROGRAM TwoFunctions

A Important Note

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/place.html (2 of 3)8/5/2006 8:10:10 PM


Where Do My Functions Go?

Although in general a function can "contain" other


functions,
an internal function CANNOT contain any other functions.

In the following example, the main program "contains" an internal function


InternalFunction(), which in turn contains another internal function Funct(). This is
incorrect, since an internal function cannot contain another internal function. In other
words, the internal functions of a main program must be on the same level.

PROGRAM Wrong
IMPLICIT NONE
.........
CONTAINS
INTEGER FUNCTION InternalFunction(.....)
IMPLICIT NONE
........
CONTAINS
REAL FUNCTION Funct(.....)
IMPLICIT NONE
........
END FUNCTION Funct
END FUNCTION InternalFunction
END PROGRAM Wrong

Please continue with the next important topic about scope rules.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/place.html (3 of 3)8/5/2006 8:10:10 PM


Scope Rules

Scope Rules

Since a main program could contain many functions and in fact a function can contain other functions (i.e., nested
functions), one may ask the following questions:

1. Could a function use a variable declared in the main program?


2. Could a main program use a variable declared in one of its function?

The scope rules answer these questions. In fact, scope rules tell us if an entity (i.e., variable, parameter and function) is
"visible" or accessible at certain places. Thus, places where an entity can be accessed or visible is referred to the scope of
that entity.

The simplest rule is the following:

Scope Rule The scope of an entity is the program or function


1 in which it is declared.

Therefore, in the following, the scope of parameter PI and variables m and n is the main program, the scope of formal
argument k and REAL variables f and g is function Funct1(), and the scope of formal arguments u and v is function Funct2
().

PROGRAM Scope_1
IMPLICIT NONE
REAL, PARAMETER :: PI = 3.1415926
INTEGER :: m, n
...................
CONTAINS
INTEGER FUNCTION Funct1(k)
IMPLICIT NONE
INTEGER, INTENT(IN) :: k
REAL :: f, g
..........
END FUNCTION Funct1

REAL FUNCTION Funct2(u, v)


IMPLICIT NONE
REAL, INTENT(IN) :: u, v
..........
END FUNCTION Funct2
END PROGRAM Scope_1

There is a direct consequence of Scope Rule 1. Since an entity declared in a function has a scope of that function, this entity
cannot be seen from outside of the function. In the above example, formal argument k and variables f and g are declared
within function Funct1(), they are only "visible" in function Funct1() and are not visible outside of Funct1(). In other
words, since k, f and g are not "visible" from the main program and function Funct2(), they cannot be used in the main

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/scope.html (1 of 4)8/5/2006 8:10:12 PM


Scope Rules

program and function Funct2(). Similarly, the main program and function Funct1() cannot use the formal arguments u and
v and any entity declared in function Funct2().

Local Entities

Due to the above discussion, the entities declared in a function or in the main program are said local to that function or the
main program. Thus, k, f and g are local to function Funct1(), u and v are local to function Funct2(), and PI, m and n are
local to the main program.

Global Entities

Given a function f(), entities that are declared in all containing functions or the main program are said global to f(). In the
above example, since variables m and n are declared in the main program, they are global to Funct1() and function Funct2
(). However, variables f and g are not global to function Funct2(), since Funct1() does not contain Funct2(). Similarly,
formal arguments u and v are not global to function Funct1().

This comes the second scope rule:

A global entity is visible to all contained functions,


Scope Rule
including the function in which that entity is
2
declared.

Continue with the above example, since m and n are global to both functions Funct1() and Funct2(), they can be used in
these two functions.

PROGRAM Scope_2
IMPLICIT NONE
INTEGER :: a = 1, b = 2, c = 3

WRITE(*,*) Add(a)
c = 4
WRITE(*,*) Add(a)
WRITE(*,*) Mul(b,c)

CONTAINS
INTEGER FUNCTION Add(q)
IMPLICIT NONE
INTEGER, INTENT(IN) :: q
Add = q + c
END FUNCTION Add

INTEGER FUNCTION Mul(x, y)


IMPLICIT NONE
INTEGER, INTENT(IN) :: x, y
Mul = x * y
END FUNCTION Mul
END PROGRAM Scope_2

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/scope.html (2 of 4)8/5/2006 8:10:12 PM


Scope Rules

In the above program, variables a, b and c are global to both functions Add() and Mul(). Therefore, since variable c used in
function Add() is global to Add(), expression q + c means computing the sum of the value of the formal argument q and
the value of global variable c. Therefore, the first WRITE produces 4 (= 1 + 3). Before the second WRITE, the value of c
is changed to 4 in the main program. Hence, the second WRITE produces 5 (= 1 + 4). The third WRITE produces 8 (= 2 *
4).

Thus, the first two WRITEs produce different results even though their actual arguments are the same! This is usually
refereed to as a side effect. Therefore, if it is possible, avoid using global variables in internal functions.

Let us continue with the above example. To remove side effect, one could add one more argument to function Add() for
passing the value of c.

PROGRAM Scope_2
IMPLICIT NONE
INTEGER :: a = 1, b = 2, c = 3

WRITE(*,*) Add(a, c)
c = 4
WRITE(*,*) Add(a, c)
WRITE(*,*) Mul(b,c)

CONTAINS
INTEGER FUNCTION Add(q, h)
IMPLICIT NONE
INTEGER, INTENT(IN) :: q, h
Add = q + h
END FUNCTION Add

INTEGER FUNCTION Mul(x, y)


IMPLICIT NONE
INTEGER, INTENT(IN) :: x, y
Mul = x * y
END FUNCTION Mul
END PROGRAM Scope_2

What If There Are Name Conflicts?

Frequently we may have a local entity whose name is identical to the name of a global entity. To resolve this name conflict,
we need the following new scope rule:

Scope Rule An entity declared in the scope of another entity is always


3 a different entity even if their names are identical.

In the program below, the main program declares a variable i, which is global to function Sum(). However, i is also
declared in function Sum(). According to Scope Rule 3 above, these two is are two different entities. More precisely, when
the value of Sum()'s i is changed, this change will not affect the i in the main program and vice versa. This would save us a
lot of time in finding variables with different names.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/scope.html (3 of 4)8/5/2006 8:10:12 PM


Scope Rules

PROGRAM Scope_3
IMPLICIT NONE
INTEGER :: i, Max = 5

DO i = 1, Max
Write(*,*) Sum(i)
END DO

CONTAINS

INTEGER FUNCTION Sum(n)


IMPLICIT NONE
INTEGER, INTENT(IN) :: n
INTEGER :: i, s
s = 0
DO i = 1, n
s = s + i
END DO
Sum = s
END FUNCTION Sum
END PROGRAM Scope_3

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/scope.html (4 of 4)8/5/2006 8:10:12 PM


Commuting Cubes

Computing Cubes

Problem Statement

Write a program to compute the cubes of 1, 2, 3, ..., 10 in both INTEGER and REAL types. It is required to write a
function intCube() for computing the cube of an integer and a function realCube() for computing the cube of a real.

Solution

! -----------------------------------------------------
! This program display the cubes of INTEGERs and
! REALs. The cubes are computed with two functions:
! intCube() and realCube().
! -----------------------------------------------------

PROGRAM Cubes
IMPLICIT NONE

INTEGER, PARAMETER :: Iterations = 10


INTEGER :: i
REAL :: x

DO i = 1, Iterations
x = i
WRITE(*,*) i, x, intCube(i), realCube(x)
END DO

CONTAINS

! -----------------------------------------------------
! INTEGER FUNCTION intCube() :
! This function returns the cube of the argument.
! -----------------------------------------------------

INTEGER FUNCTION intCube(Number)


IMPLICIT NONE

INTEGER, INTENT(IN) :: Number

intCube = Number*Number*Number
END FUNCTION intCube

! -----------------------------------------------------
! REAL FUNCTION realCube() :
! This function returns the cube of the argument.
! -----------------------------------------------------

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/cube.html (1 of 2)8/5/2006 8:10:13 PM


Commuting Cubes

REAL FUNCTION realCube(Number)


IMPLICIT NONE

REAL, INTENT(IN) :: Number

realCube = Number*Number*Number
END FUNCTION realCube

END PROGRAM Cubes

Click here to download this program.

Program Input and Output

The following is the output from the above program.

1, 1., 1, 1.
2, 2., 8, 8.
3, 3., 27, 27.
4, 4., 64, 64.
5, 5., 125, 125.
6, 6., 216, 216.
7, 7., 343, 343.
8, 8., 512, 512.
9, 9., 729, 729.
10, 10., 1000, 1000.

Discussion

● Functions intCube() and realCube() are identical except for the types of formal arguments and returned values.
● The main program has a DO-loop that iterates Iterations times (this is a PARAMETER, or an alias, of 10).
Variable x holds the real value of integer variable i.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/cube.html (2 of 2)8/5/2006 8:10:13 PM


Commuting Means - Revisited

Computing Means - Revisited

Problem Statement

The arithmetic, geometric and harmonic means of three positive numbers are defined by the following formulas:

Write a program to read three positive numbers and use three functions to compute the arithmetic, geometric and harmonic
means.

Solution

! ----------------------------------------------------------
! This program contains three functions for computing the
! arithmetic, geometric and harmonic means of three REALs.
! ----------------------------------------------------------

PROGRAM ComputingMeans
IMPLICIT NONE

REAL :: a, b, c

READ(*,*) a, b, c
WRITE(*,*) 'Input: ', a, b, c
WRITE(*,*)
WRITE(*,*) 'Arithmetic mean = ', ArithMean(a, b, c)
WRITE(*,*) 'Geometric mean = ', GeoMean(a, b, c)
WRITE(*,*) 'Harmonic mean = ', HarmonMean(a, b, c)

CONTAINS

! ----------------------------------------------------------
! REAL FUNCTION ArithMean() :
! This function computes the arithmetic mean of its
! three REAL arguments.
! ----------------------------------------------------------

REAL FUNCTION ArithMean(a, b, c)

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/means-5.html (1 of 3)8/5/2006 8:10:16 PM


Commuting Means - Revisited

IMPLICIT NONE

REAL, INTENT(IN) :: a, b, c

ArithMean = (a + b + c) /3.0
END FUNCTION ArithMean

! ----------------------------------------------------------
! REAL FUNCTION GeoMean() :
! This function computes the geometric mean of its
! three REAL arguments.
! ----------------------------------------------------------

REAL FUNCTION GeoMean(a, b, c)


IMPLICIT NONE

REAL, INTENT(IN) :: a, b, c

GeoMean = (a * b * c)**(1.0/3.0)
END FUNCTION GeoMean

! ----------------------------------------------------------
! REAL FUNCTION HarmonMean() :
! This function computes the harmonic mean of its
! three REAL arguments.
! ----------------------------------------------------------

REAL FUNCTION HarmonMean(a, b, c)


IMPLICIT NONE

REAL, INTENT(IN) :: a, b, c

HarmonMean = 3.0 / (1.0/a + 1.0/b + 1.0/c)


END FUNCTION HarmonMean

END PROGRAM ComputingMeans

Click here to download this program.

Program Input and Output

The following is the output from the above program.

Input: 10., 15., 18.

Arithmetic mean = 14.333333


Geometric mean = 13.9247675
Harmonic mean = 13.5

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/means-5.html (2 of 3)8/5/2006 8:10:16 PM


Commuting Means - Revisited

Discussion

● Each of these functions is simple and does not require further explanation.
● Note that the main program and all three functions use the same names a, b and c. By Scope Rule 3, they are all
different entities. That is, when function ArithMean() is using a, it is using its own local formal argument rather
than the global variable a declared in the main program.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/means-5.html (3 of 3)8/5/2006 8:10:16 PM


Cm and Inch Conversion

Cm and Inch Conversion

Problem Statement

It is known that 1 cm is equal to 0.3937 inch and 1 inch is equal to 2.54 cm. Write a program to convert 0, 0.5, 1, 1.5, ..., 8,
8.5, 9, 9.5, and 10 from cm to inch and from inch to cm.

Solution

! ---------------------------------------------------------------
! This program "contains" two REAL functions:
! (1) Cm_to_Inch() takes a real inch unit and converts
! it to cm unit, and
! (2) Inch_to_cm() takes a real cm unit and converts it
! to inch unit.
! The main program uses these functions to convert 0, 0.5, 1, 1.5,
! 2.0, 2.5, ..., 8.0, 8.5, 9.0, 9.5 and 10.0 inch (resp., cm) to
! cm (resp., inch).
! ---------------------------------------------------------------

PROGRAM Conversion
IMPLICIT NONE

REAL, PARAMETER :: Initial = 0.0, Final = 10.0, Step = 0.5


REAL :: x

x = Initial
DO ! x = 0, 0.5, 1.0, ..., 9.0, 9.5, 10
IF (x > Final) EXIT
WRITE(*,*) x, 'cm = ', Cm_to_Inch(x), 'inch and ', &
x, 'inch = ', Inch_to_Cm(x), 'cm'
x = x + Step
END DO

CONTAINS

! ---------------------------------------------------------------
! REAL FUNCTION Cm_to_Inch()
! This function converts its real input in cm to inch.
! ---------------------------------------------------------------

REAL FUNCTION Cm_to_Inch(cm)


IMPLICIT NONE

REAL, INTENT(IN) :: cm
REAL, PARAMETER :: To_Inch = 0.3937 ! conversion factor

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/convert.html (1 of 3)8/5/2006 8:10:18 PM


Cm and Inch Conversion

Cm_to_Inch = To_Inch * cm
END FUNCTION Cm_to_Inch

! ---------------------------------------------------------------
! REAL FUNCTION Inch_to_Cm()
! This function converts its real input in inch to cm.
! ---------------------------------------------------------------

REAL FUNCTION Inch_to_Cm(inch)


IMPLICIT NONE

REAL, INTENT(IN) :: inch


REAL, PARAMETER :: To_Cm = 2.54 ! conversion factor

Inch_to_Cm = To_Cm * inch


END FUNCTION Inch_to_Cm

END PROGRAM Conversion

Click here to download this program.

Program Input and Output

The following is the output from the above program.

0.E+0cm = 0.E+0inch and 0.E+0inch = 0.E+0cm


0.5cm = 0.196850002inch and 0.5inch = 1.26999998cm
1.cm = 0.393700004inch and 1.inch = 2.53999996cm
1.5cm = 0.590550005inch and 1.5inch = 3.80999994cm
2.cm = 0.787400007inch and 2.inch = 5.07999992cm
2.5cm = 0.984250009inch and 2.5inch = 6.3499999cm
3.cm = 1.18110001inch and 3.inch = 7.61999989cm
3.5cm = 1.37794995inch and 3.5inch = 8.88999939cm
4.cm = 1.57480001inch and 4.inch = 10.1599998cm
4.5cm = 1.77165008inch and 4.5inch = 11.4300003cm
5.cm = 1.96850002inch and 5.inch = 12.6999998cm
5.5cm = 2.16534996inch and 5.5inch = 13.9699993cm
6.cm = 2.36220002inch and 6.inch = 15.2399998cm
6.5cm = 2.55905008inch and 6.5inch = 16.5100002cm
7.cm = 2.75589991inch and 7.inch = 17.7799988cm
7.5cm = 2.95274997inch and 7.5inch = 19.0499992cm
8.cm = 3.14960003inch and 8.inch = 20.3199997cm
8.5cm = 3.34645009inch and 8.5inch = 21.5900002cm
9.cm = 3.54330015inch and 9.inch = 22.8600006cm
9.5cm = 3.74014997inch and 9.5inch = 24.1299992cm
10.cm = 3.93700004inch and 10.inch = 25.3999996cm

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/convert.html (2 of 3)8/5/2006 8:10:18 PM


Cm and Inch Conversion

Discussion

● Function Cm_to_Inch() converts its formal argument cm to inch, which is returned as the function value. Please
note that the constant 0.3937 is defined as a PARAMETER.
● Function Inch_to_Cm() converts its formal argument inch to cm, which is returned as the function value. Please
note that the constant 2.54 is defined as a PARAMETER.
● The main program uses DO-EXIT-END DO to generate 0, 0.5, 1, 1.5, ..., 8, 8.5, 9, 9.5 and 10. For each value,
Cm_to_Inch() and Inch_to_Cm() are called to perform the desired conversion.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/convert.html (3 of 3)8/5/2006 8:10:18 PM


Heron's Formula for Computing Triangle Area - Revisited

Heron's Formula for Computing Triangle Area - Revisited

Problem Statement

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:

In order for a, b and c to form a triangle, two conditions must be satisfied. First, all side lengths must be positive:

Second, the sum of any two side lengths must be greater than the third side length:

Write a program to read in three real values and use a function for testing the conditions and another function for computing
the area. Should the conditions fail, your program must keep asking the user to re-enter the input until the input form a
triangle. Then, the other function is used to compute the area.

Solution

! --------------------------------------------------------------------
! This program uses Heron's formula to compute the area of a
! triangle. It "contains" the following functions;
! (1) LOGICAL function TriangleTest() -
! this function has three real formal arguments and tests
! to see if they can form a triangle. If they do form a
! triangle, this function returns .TRUE.; otherwise, it
! returns .FALSE.
! (2) REAL function TriangleArea() -
! this functions has three real formal arguments considered
! as three sides of a triangle and returns the area of this
! triangle.
! --------------------------------------------------------------------

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/area-2.html (1 of 3)8/5/2006 8:10:21 PM


Heron's Formula for Computing Triangle Area - Revisited

PROGRAM HeronFormula
IMPLICIT NONE

REAL :: a, b, c, TriangleArea

DO
WRITE(*,*) 'Three sides of a triangle please --> '
READ(*,*) a, b, c
WRITE(*,*) 'Input sides are ', a, b, c
IF (TriangleTest(a, b, c)) EXIT ! exit if not a triangle
WRITE(*,*) 'Your input CANNOT form a triangle. Try again'
END DO

TriangleArea = Area(a, b, c)
WRITE(*,*) 'Triangle area is ', TriangleArea

CONTAINS

! --------------------------------------------------------------------
! LOGICAL FUNCTION TriangleTest() :
! This function receives three REAL numbers and tests if they form
! a triangle by testing:
! (1) all arguments must be positive, and
! (2) the sum of any two is greater than the third
! If the arguments form a triangle, this function returns .TRUE.;
! otherwise, it returns .FALSE.
! --------------------------------------------------------------------

LOGICAL FUNCTION TriangleTest(a, b, c)


IMPLICIT NONE

REAL, INTENT(IN) :: a, b, c
LOGICAL :: test1, test2

test1 = (a > 0.0) .AND. (b > 0.0) .AND. (c > 0.0)


test2 = (a + b > c) .AND. (a + c > b) .AND. (b + c > a)
TriangleTest = test1 .AND. test2 ! both must be .TRUE.
END FUNCTION TriangleTest

! --------------------------------------------------------------------
! REAL FUNCTION Area() :
! This function takes three real number that form a triangle, and
! computes and returns the area of this triangle using Heron's formula.
! --------------------------------------------------------------------

REAL FUNCTION Area(a, b, c)


IMPLICIT NONE

REAL, INTENT(IN) :: a, b, c
REAL :: s

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/area-2.html (2 of 3)8/5/2006 8:10:21 PM


Heron's Formula for Computing Triangle Area - Revisited

s = (a + b + c) / 2.0
Area = SQRT(s*(s-a)*(s-b)*(s-c))
END FUNCTION Area

END PROGRAM HeronFormula

Click here to download this program.

Program Input and Output

The following is the output from the above program.

Three sides of a triangle please -->


-3.0 4.0 5.0
Input sides are -3., 4., 5.
Your input CANNOT form a triangle. Try again
Three sides of a triangle please -->
1.0 3.0 4.0
Input sides are 1., 3., 4.
Your input CANNOT form a triangle. Try again
Three sides of a triangle please -->
6.0 8.0 10.0
Input sides are 6., 8., 10.
Triangle area is 24.

Discussion

● LOGICAL function TriangleTest() receives three REAL values. The result of the first test condition is saved to a
local LOGICAL variable test1, while the result of the second condition is saved to another LOGICAL variable
test2. Since both conditions must be true to have a triangle, test1 and test2 are .AND.ed and the result goes into the
function name so that it could be returned.
● REAL function Area is simple and does not require further discussion. However, please note that Area() has three
formal arguments whose names are identical to the three global variables declared in the main program. By Scope
Rule 3, they are different entities and do not cause any conflicts.
● The main program has a DO-EXIT-END DO loop. In each iteration, it asks for three real values. These values are
sent to LOGICAL function TriangleTest() for testing. If the returned value is .TRUE., the input form a triangle
and the control of execution exits. Then, the area is computed with REAL function Area(). If the returned value is .
FALSE., this function displays a message and goes back asking for a new set of values.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/area-2.html (3 of 3)8/5/2006 8:10:21 PM


Commuting the Combinatorial Coefficient

Commuting the Combinatorial Coefficient

Problem Statement

The combinatorial coefficient C(n,r) is defined as follows:

where 0 <= r <= n must hold. Write a program that keeps reading in values for n and r, exits if both values are zeros, uses a
LOGICAL function to test if 0 <= r <= n holds, and computes C(n,r) with an INTEGER function.

Solution

! ---------------------------------------------------------------
! This program computes the combinatorial coefficient C(n,r):
!
! n!
! C(n,r) = -------------
! r! x (n-r)!
!
! It asks for two integers and uses Cnr(n,r) to compute the value.
! If 0 <= r <= n does not hold, Cnr() returns -1 so that the main
! program would know the input values are incorrect. Otherwise,
! Cnr() returns the desired combinatorial coefficient.
!
! Note that if the input values are zeros, this program stops.
! ---------------------------------------------------------------

PROGRAM Combinatorial
IMPLICIT NONE

INTEGER :: n, r, Answer

DO
WRITE(*,*)
WRITE(*,*) "Two integers n and r (0 <= r <= n) please "
WRITE(*,*) "0 0 to stop --> "
READ(*,*) n, r
IF (n == 0 .AND. r == 0) EXIT
WRITE(*,*) "Your input:"
WRITE(*,*) " n = ", n
WRITE(*,*) " r = ", r
Answer = Cnr(n, r)

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/cnr-1.html (1 of 4)8/5/2006 8:10:24 PM


Commuting the Combinatorial Coefficient

IF (Answer < 0) THEN


WRITE(*,*) "Incorrect input"
ELSE
WRITE(*,*) " C(n,r) = ", Answer
END IF
END DO

CONTAINS

! ---------------------------------------------------------------
! INTEGER FUNCTION Cnr(n,r)
! This function receives n and r, uses LOGICAL function Test()
! to verify if the condition 0 <= r <= n holds, and uses
! Factorial() to compute n!, r! and (n-r)!.
! ---------------------------------------------------------------

INTEGER FUNCTION Cnr(n, r)


IMPLICIT NONE
INTEGER, INTENT(IN) :: n, r

IF (Test(n,r)) THEN
Cnr = Factorial(n)/(Factorial(r)*Factorial(n-r))
ELSE
Cnr = -1
END IF
END FUNCTION Cnr

! ---------------------------------------------------------------
! LOGICAL FUNCTION Test()
! This function receives n and r. If 0 <= r <= n holds, it
! returns .TRUE.; otherwise, it returns .FALSE.
! ---------------------------------------------------------------

LOGICAL FUNCTION Test(n, r)


IMPLICIT NONE
INTEGER, INTENT(IN) :: n, r

Test = (0 <= r) .AND. (r <= n)


END FUNCTION Test

! ---------------------------------------------------------------
! INTEGER FUNCTION Factorial()
! This function receives a non-negative integer and computes
! its factorial.
! ---------------------------------------------------------------

INTEGER FUNCTION Factorial(k)


IMPLICIT NONE
INTEGER, INTENT(IN) :: k
INTEGER :: Ans, i

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/cnr-1.html (2 of 4)8/5/2006 8:10:24 PM


Commuting the Combinatorial Coefficient

Ans = 1
DO i = 1, k
Ans = Ans * i
END DO
Factorial = Ans
END FUNCTION Factorial

END PROGRAM Combinatorial

Click here to download this program.

Program Input and Output

The following is the output from the above program.

Two integers n and r (0 <= r <= n) please


0 0 to stop -->
10 4
Your input:
n = 10
r = 4
C(n,r) = 210

Two integers n and r (0 <= r <= n) please


0 0 to stop -->
7 6
Your input:
n = 7
r = 6
C(n,r) = 7

Two integers n and r (0 <= r <= n) please


0 0 to stop -->
4 8
Your input:
n = 4
r = 8
Incorrect input

Two integers n and r (0 <= r <= n) please


0 0 to stop -->
-3 5
Your input:
n = -3
r = 5
Incorrect input

Two integers n and r (0 <= r <= n) please


0 0 to stop -->

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/cnr-1.html (3 of 4)8/5/2006 8:10:24 PM


Commuting the Combinatorial Coefficient

0 0

In the sample output above, please note the error messages indicating that condition 0 <= r <= n does not hold. Please also
note that the program stops when the input values are 0 and 0.

Discussion

● The function that computes the combinatorial coefficient is INTEGER function Cnr(n,r). Since it must compute n!,
r! and (n-r)!, it would be better to write a function to compute the factorial of an integer. In this way, Cnr() would
just use Factorial() three times rather than using three DO-loops. Note that if the condition does not hold, Cnr()
returns -1.
● INTEGER function Factorial() computes the factorial of its formal argument.
● LOGICAL function Test() is very simple. If condition 0 <= r <= n holds, Test receives .TRUE.; otherwise, it
receives .FALSE.
● The main program has a DO-EXIT-END DO. It asks for two integers and indicates that the program will stop if
both values are zeros. Then, Cnr() is used for computing the combinatorial coefficient. If the returned value is
negative, the input values do not meet the condition and an error message is displayed. Otherwise, the combinatorial
coefficient is shown.
● Note that all three functions are internal functions of the main program.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/cnr-1.html (4 of 4)8/5/2006 8:10:24 PM


Computing Square Roots with Newton's Method

Computing Square Roots with Newton's Method

Problem Statement

We have discussed Newton's Method for computing the square root of a positive number. Let the given number be b and let x
be a rough guess of the square root of b. Newton's method suggests that a better guess, New x can be computed as follows:

One can start with b as a rough guess and compute New x; from New x, one can generate a even better guess, until two
successive guesses are very close. Either one could be considered as the square root of b.

Write a function MySqrt() that accepts a formal argument and uses Newton's method to computes its square root. Then, write
a main program that reads in an initial value, a final value, and a step size, and computes the square roots of these successive
values with Newton'e method and Fortran's SQRT() function, and determines the absolute error.

Solution

! ---------------------------------------------------------------
! This program contains a function MySqrt() that uses Newton's
! method to find the square root of a positive number. This is
! an iterative method and the program keeps generating better
! approximation of the square root until two successive
! approximations have a distance less than the specified tolerance.
! ---------------------------------------------------------------

PROGRAM SquareRoot
IMPLICIT NONE

REAL :: Begin, End, Step


REAL :: x, SQRTx, MySQRTx, Error

READ(*,*) Begin, End, Step ! read in init, final and step


x = Begin ! x starts with the init value
DO
IF (x > End) EXIT ! exit if x > the final value
SQRTx = SQRT(x) ! find square root with SQRT()
MySQRTx = MySqrt(x) ! do the same with my sqrt()
Error = ABS(SQRTx - MySQRTx) ! compute the absolute error
WRITE(*,*) x, SQRTx, MySQRTx, Error ! display the results
x = x + Step ! move on to the next value
END DO

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/sqrt-1.html (1 of 3)8/5/2006 8:10:27 PM


Computing Square Roots with Newton's Method

CONTAINS

! ---------------------------------------------------------------
! REAL FUNCTION MySqrt()
! This function uses Newton's method to compute an approximate
! of a positive number. If the input value is zero, then zero is
! returned immediately. For convenience, the absolute value of
! the input is used rather than kill the program when the input
! is negative.
! ---------------------------------------------------------------

REAL FUNCTION MySqrt(Input)


IMPLICIT NONE
REAL, INTENT(IN) :: Input
REAL :: X, NewX
REAL, PARAMETER :: Tolerance = 0.00001

IF (Input == 0.0) THEN ! if the input is zero


MySqrt = 0.0 ! returns zero
ELSE ! otherwise,
X = ABS(Input) ! use absolute value
DO ! for each iteration
NewX = 0.5*(X + Input/X) ! compute a new approximation
IF (ABS(X - NewX) < Tolerance) EXIT ! if very close, exit
X = NewX ! otherwise, keep the new one
END DO
MySqrt = NewX
END IF
END FUNCTION MySqrt

END PROGRAM SquareRoot

Click here to download this program.

Program Input and Output

If the input values of Begin, End and Step are 0.0, 10.0 and 0.5, the following is the output from the above program.

0.E+0, 0.E+0, 0.E+0, 0.E+0


0.5, 0.707106769, 0.707106769, 0.E+0
1., 1., 1., 0.E+0
1.5, 1.22474492, 1.2247448, 1.192092896E-7
2., 1.41421354, 1.41421354, 0.E+0
2.5, 1.58113885, 1.58113885, 0.E+0
3., 1.73205078, 1.7320509, 1.192092896E-7
3.5, 1.87082875, 1.87082863, 1.192092896E-7
4., 2., 2., 0.E+0
4.5, 2.12132025, 2.12132025, 0.E+0
5., 2.23606801, 2.23606801, 0.E+0
5.5, 2.34520793, 2.34520793, 0.E+0

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/sqrt-1.html (2 of 3)8/5/2006 8:10:27 PM


Computing Square Roots with Newton's Method

6., 2.44948983, 2.44948959, 2.384185791E-7


6.5, 2.54950976, 2.54950976, 0.E+0
7., 2.64575124, 2.64575148, 2.384185791E-7
7.5, 2.73861289, 2.73861265, 2.384185791E-7
8., 2.82842708, 2.82842708, 0.E+0
8.5, 2.91547585, 2.91547585, 0.E+0
9., 3., 3., 0.E+0
9.5, 3.08220696, 3.08220696, 0.E+0
10., 3.1622777, 3.1622777, 0.E+0

Discussion

This program has nothing special. Please refer to the discussion of Newton's method for the computation details of function
MySqrt(). However, there is one thing worth to be mentioned. Since the formal argument Input is declared with INTENT
(IN), it cannot be changed in function MySqrt(). Therefore, the value of the formal argument Input is copied to X and used
in square root computation.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/sqrt-1.html (3 of 3)8/5/2006 8:10:27 PM


Designing a Greatest Common Divisor Function

Designing a Greatest Common Divisor Function

Problem Statement

We have seen Greatest Common Divisor computation. This problem uses the same idea; but the computation is performed
with a function.

Solution

! ---------------------------------------------------------
! This program computes the GCD of two positive integers
! using the Euclid method. Given a and b, a >= b, the
! Euclid method goes as follows: (1) dividing a by b yields
! a reminder c; (2) if c is zero, b is the GCD; (3) if c is
! no zero, b becomes a and c becomes c and go back to
! Step (1). This process will continue until c is zero.
!
! Euclid's algorithm is implemented as an INTEGER function
! GCD().
! ---------------------------------------------------------

PROGRAM GreatestCommonDivisor
IMPLICIT NONE

INTEGER :: a, b

WRITE(*,*) 'Two positive integers please --> '


READ(*,*) a, b
WRITE(*,*) 'The GCD of is ', GCD(a, b)

CONTAINS

! ---------------------------------------------------------
! INTEGER FUNCTION GCD():
! This function receives two INTEGER arguments and
! computes their GCD.
! ---------------------------------------------------------

INTEGER FUNCTION GCD(x, y)


IMPLICIT NONE

INTEGER, INTENT(IN) :: x, y ! we need x and y here


INTEGER :: a, b, c

a = x ! if x <= y, swap x and y

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/gcd-2.html (1 of 2)8/5/2006 8:10:29 PM


Designing a Greatest Common Divisor Function

b = y ! since x and y are declared with


IF (a <= b) THEN ! INTENT(IN), they cannot be
c = a ! involved in this swapping process.
a = b ! So, a, b and c are used instead.
b = c
END IF

DO
c = MOD(a, b)
IF (c == 0) EXIT
a = b
b = c
END DO

GCD = b
END FUNCTION GCD

END PROGRAM GreatestCommonDivisor

Click here to download this program.

Program Input and Output

The following is the output from the above program.

Two positive integers please -->


46332 71162
The GCD of is 26

Discussion

Nothing special is here. As in the previous example, since x and y are declared with INTENT(IN), their values cannot be
modified and therefore their values are copies to a and b to be used in other computation.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/gcd-2.html (2 of 2)8/5/2006 8:10:29 PM


Finding All Prime Numbers in the Range of 2 and N - Revisited

Finding All Prime Numbers in the Range of 2 and N -


Revisited

Problem Statement

We have discussed a method for finding all prime numbers in the range of 2 and N previously. In fact, one can design a
function with an INTEGER formal argument and returns .TRUE. if the argument is a prime number. Then, it is used to test
if the integers in the range of 2 and N are integers.

Solution

! --------------------------------------------------------------------
! This program finds all prime numbers in the range of 2 and an
! input integer.
! --------------------------------------------------------------------

PROGRAM Primes
IMPLICIT NONE

INTEGER :: Range, Number, Count

Range = GetNumber()
Count = 1 ! input is correct. start counting
WRITE(*,*) ! since 2 is a prime
WRITE(*,*) 'Prime number #', Count, ': ', 2
DO Number = 3, Range, 2 ! try all odd numbers 3, 5, 7, ...
IF (Prime(Number)) THEN
Count = Count + 1 ! yes, this Number is a prime
WRITE(*,*) 'Prime number #', Count, ': ', Number
END IF
END DO

WRITE(*,*)
WRITE(*,*) 'There are ', Count, ' primes in the range of 2 and ', Range

CONTAINS

! --------------------------------------------------------------------
! INTEGER FUNCTION GetNumber()
! This function does not require any formal argument. It keeps
! asking the reader for an integer until the input value is greater
! than or equal to 2.
! --------------------------------------------------------------------

INTEGER FUNCTION GetNumber()

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/prime-4.html (1 of 3)8/5/2006 8:10:31 PM


Finding All Prime Numbers in the Range of 2 and N - Revisited

IMPLICIT NONE

INTEGER :: Input

WRITE(*,*) 'What is the range ? '


DO ! keep trying to read a good input
READ(*,*) Input ! ask for an input integer
IF (Input >= 2) EXIT ! if it is GOOD, exit
WRITE(*,*) 'The range value must be >= 2. Your input = ', Input
WRITE(*,*) 'Please try again:' ! otherwise, bug the user
END DO
GetNumber = Input
END FUNCTION GetNumber

! --------------------------------------------------------------------
! LOGICAL FUNCTION Prime()
! This function receives an INTEGER formal argument Number. If it
! is a prime number, .TRUE. is returned; otherwise, this function
! returns .FALSE.
! --------------------------------------------------------------------

LOGICAL FUNCTION Prime(Number)


IMPLICIT NONE

INTEGER, INTENT(IN) :: Number


INTEGER :: Divisor

IF (Number < 2) THEN


Prime = .FALSE.
ELSE IF (Number == 2) THEN
Prime = .TRUE.
ELSE IF (MOD(Number,2) == 0) THEN
Prime = .FALSE.
ELSE
Divisor = 3
DO
IF (Divisor*Divisor>Number .OR. MOD(Number,Divisor)==0) EXIT
Divisor = Divisor + 2
END DO
Prime = Divisor*Divisor > Number
END IF
END FUNCTION Prime

END PROGRAM Primes

Click here to download this program.

Program Input and Output

The following is the output from the above program.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/prime-4.html (2 of 3)8/5/2006 8:10:31 PM


Finding All Prime Numbers in the Range of 2 and N - Revisited

What is the range ?


-10
The range value must be >= 2. Your input = -10
Please try again:
0
The range value must be >= 2. Your input = 0
Please try again:
60

Prime number #1: 2


Prime number #2: 3
Prime number #3: 5
Prime number #4: 7
Prime number #5: 11
Prime number #6: 13
Prime number #7: 17
Prime number #8: 19
Prime number #9: 23
Prime number #10: 29
Prime number #11: 31
Prime number #12: 37
Prime number #13: 41
Prime number #14: 43
Prime number #15: 47
Prime number #16: 53
Prime number #17: 59

There are 17 primes in the range of 2 and 60

Discussion

● Function GetNumber() has no formal arguments. It keeps asking the user to input an integer that is greater than or
equal to two. The valid input is returned as the function value.
● The core part of this program is LOGICAL function Prime(). It receives an INTEGER formal argument Number
and returns .TRUE. if Number is a prime number. For the working detail and logic of this function, please click here
to bring you to the example discussed previously.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/prime-4.html (3 of 3)8/5/2006 8:10:31 PM


The Bisection (Bozano) Equation Solver

The Bisection (Bozano) Equation Solver

Problem Statement

Given a continuous equation f(x)=0 and two values a and b (a < b), if f(a)*f(b) < 0 (i.e., f(a) and f(b) have opposite signs),
it can be proved that there exists a root of f(x)=0 between a and b. More precisely, there exists a c, a <= c <= b, such that f
(c)=0 holds.

This result provides us with a method for solving equations. If we take the midpoint of a and b, c=(a+b)/2, and computes its
function value f(c), we have the following cases:

1. If f(c) is very small (i.e., smaller than a tolerance value), then c can be considered as a root of f(x)=0 and we are
done.
2. Otherwise, since f(a) and f(b) have opposite signs, the sign of f(c) is either identical to that of f(a) or that of f(b).
❍ If the sign of f(c) is different from that of f(a), then since f(a) and f(c) have opposite signs, f(x)=0 has a root

in the range of a and c.


❍ If the sign of f(c) is different from that of f(b), then since f(b) and f(c) have opposite signs, f(x)=0 has a root

in the range of c and b.


3. Therefore, if the original interval [a,b] is replaced with [a,c] in the first case or replaced with [c,b] in the second
case, the length of the interval is reduced by half. If continue this process, after a number of steps, the length of the
interval could be very small. However, since this small interval still contains a root of f(x)=0, we actually find an
approximation of that root!

Write a program that contains two functions: (1) Funct() - the function f(x) and (2) Solve() - the equation solver based on
the above theory. Then, reads in a and b and uses function Solve() to find a root in the range of a and b. Note that before
calling Solve, your program should check if f(a)*f(b)<0 holds.

Your function Funct() is given below:

This function has a root near -0.89.

Since this process keeps dividing the intervals into two equal halves, it is usually referred to as the bisection method. It is
also known as Bozano's method.

Solution

! --------------------------------------------------------------------
! This program solves equations with the Bisection Method. Given
! a function f(x) = 0. The bisection method starts with two values,
! a and b such that f(a) and f(b) have opposite signs. That is,

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/bisect.html (1 of 5)8/5/2006 8:10:39 PM


The Bisection (Bozano) Equation Solver

! f(a)*f(b) < 0. Then, it is guaranteed that f(x)=0 has a root in


! the range of a and b. This program reads in a and b (Left and Right
! in this program) and find the root in [a,b].
! In the following, function f() is REAL FUNCTION Funct() and
! solve() is the function for solving the equation.
! --------------------------------------------------------------------

PROGRAM Bisection
IMPLICIT NONE

REAL, PARAMETER :: Tolerance = 0.00001


REAL :: Left, fLeft
REAL :: Right, fRight
REAL :: Root

WRITE(*,*) 'This program can solves equation F(x) = 0'


WRITE(*,*) 'Please enter two values Left and Right such that '
WRITE(*,*) 'F(Left) and F(Right) have opposite signs.'
WRITE(*,*)
WRITE(*,*) 'Left and Right please --> '
READ(*,*) Left, Right ! read in Left and Right

fLeft = Funct(Left) ! compute their function values


fRight = Funct(Right)
WRITE(*,*)
WRITE(*,*) 'Left = ', Left, ' f(Left) = ', fLeft
WRITE(*,*) 'Right = ', Right, ' f(Right) = ', fRight
WRITE(*,*)
IF (fLeft*fRight > 0.0) THEN
WRITE(*,*) '*** ERROR: f(Left)*f(Right) must be negative ***'
ELSE
Root = Solve(Left, Right, Tolerance)
WRITE(*,*) 'A root is ', Root
END IF

CONTAINS

! --------------------------------------------------------------------
! REAL FUNCTION Funct()
! This is for function f(x). It takes a REAL formal argument and
! returns the value of f() at x. The following is sample function
! with a root in the range of -10.0 and 0.0. You can change the
! expression with your own function.
! --------------------------------------------------------------------

REAL FUNCTION Funct(x)


IMPLICIT NONE
REAL, INTENT(IN) :: x
REAL, PARAMETER :: PI = 3.1415926
REAL, PARAMETER :: a = 0.8475

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/bisect.html (2 of 5)8/5/2006 8:10:39 PM


The Bisection (Bozano) Equation Solver

Funct = SQRT(PI/2.0)*EXP(a*x) + x/(a*a + x*x)

END FUNCTION Funct

! --------------------------------------------------------------------
! REAL FUNCTION Solve()
! This function takes Left - the left end, Right - the right end,
! and Tolerance - a tolerance value such that f(Left)*f(Right) < 0
! and find a root in the range of Left and Right.
! This function works as follows. Because of INTENT(IN), this
! function cannot change the values of Left and Right and therefore
! the values of Left and Right are saved to a and b.
! Then, the middle point c=(a+b)/2 and its function value f(c)
! is computed. If f(a)*f(c) < 0, then a root is in [a,c]; otherwise,
! a root is in [c,b]. In the former case, replacing b and f(b) with
! c and f(c), we still maintain that a root in [a,b]. In the latter,
! replacing a and f(a) with c and f(c) will keep a root in [a,b].
! This process will continue until |f(c)| is less than Tolerance and
! hence c can be considered as a root.
! --------------------------------------------------------------------

REAL FUNCTION Solve(Left, Right, Tolerance)


IMPLICIT NONE
REAL, INTENT(IN) :: Left, Right, Tolerance
REAL :: a, Fa, b, Fb, c, Fc

a = Left ! save Left and Right


b = Right

Fa = Funct(a) ! compute the function values


Fb = Funct(b)
IF (ABS(Fa) < Tolerance) THEN ! if f(a) is already small
Solve = a ! then a is a root
ELSE IF (ABS(Fb) < Tolerance) THEN ! is f(b) is small
Solve = b ! then b is a root
ELSE ! otherwise,
DO ! iterate ....
c = (a + b)/2.0 ! compute the middle point
Fc = Funct(c) ! and its function value
IF (ABS(Fc) < Tolerance) THEN ! is it very small?
Solve = c ! yes, c is a root
EXIT
ELSE IF (Fa*Fc < 0.0) THEN ! do f(a)*f(c) < 0 ?
b = c ! replace b with c
Fb = Fc ! and f(b) with f(c)
ELSE ! then f(c)*f(b) < 0 holds
a = c ! replace a with c
Fa = Fc ! and f(a) with f(c)
END IF
END DO ! go back and do it again
END IF

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/bisect.html (3 of 5)8/5/2006 8:10:39 PM


The Bisection (Bozano) Equation Solver

END FUNCTION Solve

END PROGRAM Bisection

Click here to download this program.

Program Input and Output

The following is the output from the above program with correct input:

This program solves equation F(x) = 0


Please enter two values Left and Right such that
F(Left) and F(Right) have opposite signs.

Left and Right please -->


-10.0 0.0

Left = -10. f(Left) = -9.902540594E-2


Right = 0.E+0 f(Right) = 1.25331414

A root is -0.89050293

The following output shows that the function values of the input do not have opposite signs and hence program stops.

This program solves equation F(x) = 0


Please enter two values Left and Right such that
F(Left) and F(Right) have opposite signs.

Left and Right please -->


-10.0 -1.0

Left = -10. f(Left) = -9.902540594E-2


Right = -1. f(Right) = -4.495930672E-2

*** ERROR: f(Left)*f(Right) must be negative ***

Discussion

● Function Funct(x) returns the function value at x.


● The heart of this program is function Solve(). It takes three arguments Left, Right and Tolerance and finds a root in
the range of Left and Right.
● Since arguments Left and Right are declared with INTENT(IN), their values cannot be changed. As a result, their
values are copied to variables a and b.
● The function values of a and b are stored in Fa and Fb.
● If the absolute value of Fa (resp., Fb) is very small, one can consider a (resp., b) as a root of the given equation.
● Otherwise, the midpoint c of a and b and its function value Fc are computed. If Fc is very small, c is considered as a
root.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/bisect.html (4 of 5)8/5/2006 8:10:39 PM


The Bisection (Bozano) Equation Solver

● Then if Fa and Fc have opposite signs, replacing b and Fb with c and Fc, respectively.
● If Fa and Fc have the same sign, then Fc and Fb must have the opposite sign. In this case, a and Fa are replaced
with c and Fc.
● Either way, the original interval [a,b] is replaced with a new one with half length. This process continues until the
absolute value of the function value at c, Fc, is smaller than the given tolerance value. In this case, c is considered a
root of the given equation.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/bisect.html (5 of 5)8/5/2006 8:10:39 PM


What is a Module?

What is a Module?

In many previous example, there are several internal functions packed at the end of the main program. In fact, many of
them such as Factorial(), Combinatorial(), GCD(), and Prime() are general functions that can also be used in other
programs. To provide the programmers with a way of packing commonly used functions into a few tool-boxes, Fortran 90
has a new capability called modules. It has a syntactic form very similar to a main program, except for something that are
specific to modules.

Syntax

The following is the syntax of a module:

MODULE module-name
IMPLICIT NONE
[specification part]
CONTAINS
[internal-functions]
END MODULE module-name

The differences between a program and a module are the following:

● The structure of a module is almost identical to the structure of a program.


● However, a module starts with the keyword MODULE and ends with END MODULE rather than PROGRAM
and END PROGRAM.
● A module has specification part and could contain internal function; but, it does not have any statements between
the specification part and the keyword CONTAINS.
● Consequently, a module does not contains statements to be executed as in a program. A module can only contain
declarations and functions to be used by other modules and programs. This is perhaps one of the most important
difference. As a result, a module cannot exist alone; it must be used with other modules and a main program

Short Examples

Here are some short examples of modules:

● The following is a very simple module. It has the specification part and does not have any internal function. The
specification part has two REAL PARAMETERs, namely PI and g and one INTEGER variable Counter.

MODULE SomeConstants
IMPLICIT NONE
REAL, PARAMETER :: PI = 3.1415926
REAL, PARAMETER :: g = 980
INTEGER :: Counter
END MODULE SomeConstants

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/mod-syntax.html (1 of 2)8/5/2006 8:10:41 PM


What is a Module?

● The following module SumAverage does not have any specification part (hence no IMPLICIT NONE); but it does
contain two functions, Sum() and Average(). Please note that function Average() uses Sum() to compute the sum of
three REAL numbers.

MODULE SumAverage

CONTAINS
REAL FUNCTION Sum(a, b, c)
IMPLICIT NONE
REAL, INTENT(IN) :: a, b, c
Sum = a + b + c
END FUNCTION Sum

REAL FUNCTION Average(a, b, c)


IMPLICIT NONE
REAL, INTENT(IN) :: a, b, c
Average = Sum(a,b,c)/2.0
END FUNCTION Average

END MODULE SumAverage

● The following module DegreeRadianConversion contains two PARAMETERs, PI and Degree180, and two
functions DegreeToRadian() and RadianToDegree(). The two PARAMETERs are used in the conversion
functions. Note that these parameters are global to the two functions. See scope rules for the details.

MODULE DegreeRadianConversion
IMPLICIT NONE
REAL, PARAMETER :: PI = 3.1415926
REAL, PARAMETER :: Degree180 = 180.0

REAL FUNCTION DegreeToRadian(Degree)


IMPLICIT NONE
REAL, INTENT(IN) :: Degree
DegreeToRadian = Degree*PI/Degree180
END FUNCTION DegreeToRadian

REAL FUNCTION RadianToDegree(radian)


IMPLICIT NONE
REAL, INTENT(IN) :: Radian
RadianToDegree = Radian*Degree180/PI
END FUNCTION RadianToDegree

END MODULE DegreeRadianConversion

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/mod-syntax.html (2 of 2)8/5/2006 8:10:41 PM


How to Use a Module?

How to Use a Module?

Once a module is written, its global entities (i.e., global PARAMETERs, global variables and internal functions) can be
made available to other modules and programs. The program or module that wants to use a particular module must have a
USE statement at its very beginning. The USE statement has one of the following forms:

Syntax

The following form is the syntax of a module:

USE module-name

USE module-name, ONLY: name-1, name-2, ..., name-n

Here is the meaning of these USEs:

● The first indicates that the current program or module wants to use the module whose name is module-name. For
example, the following main program indicates that it wants to use the content of module SomeConstants:

PROGRAM MainProgram
USE SomeConstants
IMPLICIT NONE
..........
END PROGRAM MainProgram

Once a USEis specified in a program or in a module, every global entities of that used module (i.e.,
PARAMETERs, variables, and internal functions) becomes available to this program or this module. For example,
if module SomeConstantsis:

MODULE SomeConstants
IMPLICIT NONE
REAL, PARAMETER :: PI = 3.1415926
REAL, PARAMETER :: g = 980
INTEGER :: Counter
END MODULE SomeConstants

Then, program MainProgramcan access to PARAMETERs PIand gand variable Counter.


● However, under many circumstances, a program or a module does not want to use everything of the used module.
For example, if program MainProgram only wants to use PARAMETER PI and variable Counter and does not
want to use g, then the second form becomes very useful. In this case, one should add the keyword ONLY followed
by a colon :, followed by a list of names that the current program or module wants to use.

PROGRAM MainProgram
USE SomeConstants, ONLY: PI, Counter
IMPLICIT NONE
..........

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/mod-use.html (1 of 3)8/5/2006 8:10:47 PM


How to Use a Module?

END PROGRAM MainProgram

Thus, MainProgramcan use PIand Counterof module SomeConstants; but, MainProgramcannot use g!

USE with ONLY: is very handy, because it could only "import" those important and vital information and "ignore"
those un-wanted ones.

● There is a third, not recommended form, that can help to rename the names of a module locally. If a module has a
name abc, in a program with a USE, one can use a new name for abc. The way of writing this renaming is the
following:

new-name => name-in-module

For example, if one wants to give a new name to Counterof module SomeConstants, one should write:

NewCounter => Counter

Thus, in a program, whenever it uses MyCounter, this program is actually using Counterof module
SomeConstants.

This kind of renaming can be used with ONLY: or without ONLY:.

PROGRAM MainProgram
USE SomeConstants, ONLY: PI, MyCounter => Counter
IMPLICIT NONE
..........
END PROGRAM MainProgram

The above example wants to use PIof module SomeConstants. In this case, when program MainProgramuses PI,
it actually uses the PIof module SomeConstants. Program MainProgramalso uses Counterof module
SomeConstants; but, in this case, since there is a renaming, when MainProgramuses MyCounterit actually uses
Counterof module SomeConstants.

Renaming does not require ONLY:. In the following, MainProgram can use all contents of module
SomeConstants. When MainProgram uses PI and g, it uses the PI and g of module SomeConstants; however,
when MainProgram uses MyCounter, it actually uses Counter of module SomeConstants.

PROGRAM MainProgram
USE SomeConstants, MyCounter => Counter
IMPLICIT NONE
..........
END PROGRAM MainProgram

Why do we need renaming? It is simple. In your program, you may have a variable whose name is identical to an
entity of a module that is being USEed. In this case, renaming the variable name would clear the ambiguity.

PROGRAM MainProgram
USE SomeConstants, GravityConstant => g
IMPLICIT NONE

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/mod-use.html (2 of 3)8/5/2006 8:10:47 PM


How to Use a Module?

INTEGER :: e, f, g
..........
END PROGRAM MainProgram

In the above example, since MainProgramhas a variable called g, which is the same as PARAMETERgin module
SomeConstants. By renaming gof SomeConstants, MainProgramcan use variable gfor the variable and
GravityConstantfor the PARAMETERgin module SomeConstants.

However, renaming is not a recommended feature. You should avoid using it whenever possible.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/mod-use.html (3 of 3)8/5/2006 8:10:47 PM


Compile Programs with Modules

Compile Programs with Modules

Normally, your programs and modules are stored in different files, all with filename suffix .f90. When you compile your
program, all involved modules must also be compiled. For example, if your program is stored in a file main.f90 and you
expect to use a few modules stored in files compute.f90, convert.f90 and constants.f90, then the following command will
compile your program and all three modules, and make an executable file a.out

f90 compute.f90 convert.f90 constants.f90 main.f90

If you do not want the executable to be called a.out, you can do the following:

f90 compute.f90 convert.f90 constants.f90 main.f90 -o main

In this case, -o main instructs the Fortran compiler to generate an executable main instead of a.out.

Different compilers may have different "personalities." This means the way of compiling modules and your
programs may be different from compilers to compilers. If you have several modules, say A, B, C, D and E, and C
uses A, D uses B, and E uses A, C and D, then the safest way to compile your program is the following command:

f90 A.f90 B.f90 C.f90 D.f90 E.f90 main.f90

That is, list those modules that do not use any other modules first, followed by those modules that only use those
listed modules, followed by your main program.

You may also compile your modules separately. For example, you may want to write and compile all modules before you
start working on your main program. The command for you to compile a single program or module without generating an
executable is the following:

f90 -c compute.f90

where -c means "compile the program without generating an executable." The output from Fortran compiler is a file whose
name is identical to the program file's name but with a file extension .o. Therefore, the above command generates a file
compute.o. The following commands compile all of your modules:

f90 -c compute.f90
f90 -c convert.f90
f90 -c constants.f90

After compiling these modules, your will see at least three files, compute.o, convert.o and constants.o.

After completing your main program, you have two choices: (1) compile your main program separately, or (2) compile your
main with all "compiled" modules. In the former, you perhaps use the following command to compile your main program:

f90 -c main.f90

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/mod-files.html (1 of 2)8/5/2006 8:10:49 PM


Compile Programs with Modules

Then, you will have a file main.o. Now you have four .o files main.o, compute.o, convert.o and constants.o. To pull them
into an executable, you need

f90 compute.o convert.o constants.o main.o

This would generate a.out. Or, you may want to use

f90 compute.o convert.o constants.o main.o -o main

so that your executable could be called main.

If you want compile your main program main.f90 with all .o files, then you need

f90 compute.o convert.o constants.o main.c

or

f90 compute.o convert.o constants.o main.c -o main

Note that the order of listing these .o files may be important. Please consult the rules discussed earlier.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/mod-files.html (2 of 2)8/5/2006 8:10:49 PM


Factorial and Combinatorial Coefficient

Factorial and Combinatorial Coefficient

Problem Statement

The combinatorial coefficient C(n,r) is defined as follows:

where 0 <= r <= n must hold. Write a module that contains two functions: (1) Factorial() and (2) Combinatorial(). The
former computes the factorial of its argument, while the latter uses the former to compute the combinatorial coefficient.
Then, write a main program that uses this module.

Solution

The following is the desired module:

! --------------------------------------------------------------------
! MODULE FactorialModule
! This module contains two procedures: Factorial(n) and
! Combinatorial(n,r). The first computes the factorial of an integer
! n and the second computes the combinatorial coefficient of two
! integers n and r.
! --------------------------------------------------------------------

MODULE FactorialModule
IMPLICIT NONE

CONTAINS

! --------------------------------------------------------------------
! FUNCTION Factorial() :
! This function accepts a non-negative integers and returns its
! Factorial.
! --------------------------------------------------------------------

INTEGER FUNCTION Factorial(n)


IMPLICIT NONE

INTEGER, INTENT(IN) :: n ! the argument


INTEGER :: Fact, i ! result

Fact = 1 ! initially, n!=1


DO i = 1, n ! this loop multiplies

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/fact-2.html (1 of 4)8/5/2006 8:10:52 PM


Factorial and Combinatorial Coefficient

Fact = Fact * i ! i to n!
END DO
Factorial = Fact

END FUNCTION Factorial

! --------------------------------------------------------------------
! FUNCTION Combinarotial():
! This function computes the combinatorial coefficient C(n,r).
! If 0 <= r <= n, this function returns C(n,r), which is computed as
! C(n,r) = n!/(r!*(n-r)!). Otherwise, it returns 0, indicating an
! error has occurred.
! --------------------------------------------------------------------

INTEGER FUNCTION Combinatorial(n, r)


IMPLICIT NONE

INTEGER, INTENT(IN) :: n, r
INTEGER :: Cnr

IF (0 <= r .AND. r <= n) THEN ! valid arguments ?


Cnr = Factorial(n) / (Factorial(r)*Factorial(n-r))
ELSE ! no,
Cnr = 0 ! zero is returned
END IF
Combinatorial = Cnr

END FUNCTION Combinatorial

END MODULE FactorialModule

Click here to download this program.

Here is the main program:

! --------------------------------------------------------------------
! PROGRAM ComputeFactorial:
! This program uses MODULE FactorialModule for computing factorial
! and combinatorial coefficients.
! --------------------------------------------------------------------

PROGRAM ComputeFactorial
USE FactorialModule ! use a module

IMPLICIT NONE

INTEGER :: N, R

WRITE(*,*) 'Two non-negative integers --> '


READ(*,*) N, R

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/fact-2.html (2 of 4)8/5/2006 8:10:52 PM


Factorial and Combinatorial Coefficient

WRITE(*,*) N, '! = ', Factorial(N)


WRITE(*,*) R, '! = ', Factorial(R)

IF (R <= N) THEN ! if r <= n, do C(n,r)


WRITE(*,*) 'C(', N, ',', R, ') = ', Combinatorial(N, R)
ELSE ! otherwise, do C(r,n)
WRITE(*,*) 'C(', R, ',', N, ') = ', Combinatorial(R, N)
END IF

END PROGRAM ComputeFactorial

Click here to download this program.

Program Input and Output

The following is the output from the above program.

Two non-negative integers -->


13 4
13! = 1932053504
4! = 24
C(13,4) = 221

Discussion

● The computation of combinatorial coefficients has been discussed in an programming example, where functions Cnr
(n,r) and Factorial(k) are internal functions of the main program.
● In this version, functions Factorial(n) and Combinatorial(n,r) are moved to a module called FactorialModule as
internal functions of that module.
● Factorial(n) takes a non-negative integer and returns its factorial.
● Combinatorial(n,r) takes two non-negative integers n and r. If 0 <= r <= n, the combinatorial coefficient C(n,r) is
returned; otherwise, 0 is returned.
● Note that in module FactorialModule, there is no variables global to its internal functions. All internal functions use
their own internal (or local) variables.
● This module does not perform many checks as in a previous programming example. But, it is not difficult to add
these tests.
● After moving the computation functions to a module, the main program becomes simpler. In the beginning, the main
program must USES FactorialModule so that functions Factorial() and Combinatorial() can be accessed from
within the main program.
● The main program reads in values for n and r. If r <= n, the combinatorial coefficient C(n,r) is computed by calling
Combinatorial(n,r); otherwise, the main program computes Combinatorial(r,n).
● If the main program and module FactorialModule are stored in files fact-1p.f90 and fact-m.f90, respectively, then
you can compile them together with the following command:

f90 fact-m.f90 fact-1p.90

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/fact-2.html (3 of 4)8/5/2006 8:10:52 PM


Factorial and Combinatorial Coefficient

or with the following that generates an executable called fact1p:

f90 fact-m.f90 fact-1p.90 -o fact-1p

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/fact-2.html (4 of 4)8/5/2006 8:10:52 PM


Trigonometric Functions Using Degree

Trigonometric Functions Using Degree

Problem Statement

Trigonometric functions (i.e., sin(x) and cos(x)) use radian for their argument. Using modules, you can design your own
trigonometric functions that use degree. Write a module that contains functions for converting radian to degree and degree
to radian and sin(x) and cos(x) with arguments in degree rather than in radian.

Solution

The following is the desired module:

! --------------------------------------------------------------------
! MODULE MyTrigonometricFunctions:
! This module provides the following functions and constants
! (1) RadianToDegree() - converts its argument in radian to
! degree
! (2) DegreeToRadian() - converts its argument in degree to
! radian
! (3) MySIN() - compute the sine of its argument in
! degree
! (4) MyCOS() - compute the cosine of its argument
! in degree
! --------------------------------------------------------------------

MODULE MyTrigonometricFunctions
IMPLICIT NONE

REAL, PARAMETER :: PI = 3.1415926 ! some constants


REAL, PARAMETER :: Degree180 = 180.0
REAL, PARAMETER :: R_to_D = Degree180/PI
REAL, PARAMETER :: D_to_R = PI/Degree180

CONTAINS

! --------------------------------------------------------------------
! FUNCTION RadianToDegree():
! This function takes a REAL argument in radian and converts it to
! the equivalent degree.
! --------------------------------------------------------------------

REAL FUNCTION RadianToDegree(Radian)


IMPLICIT NONE
REAL, INTENT(IN) :: Radian

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/trigon.html (1 of 5)8/5/2006 8:10:55 PM


Trigonometric Functions Using Degree

RadianToDegree = Radian * R_to_D


END FUNCTION RadianToDegree

! --------------------------------------------------------------------
! FUNCTION DegreeToRadian():
! This function takes a REAL argument in degree and converts it to
! the equivalent radian.
! --------------------------------------------------------------------

REAL FUNCTION DegreeToRadian(Degree)


IMPLICIT NONE
REAL, INTENT(IN) :: Degree

DegreeToRadian = Degree * D_to_R


END FUNCTION DegreeToRadian

! --------------------------------------------------------------------
! FUNCTION MySIN():
! This function takes a REAL argument in degree and computes its
! sine value. It does the computation by converting its argument to
! radian and uses Fortran's sin().
! --------------------------------------------------------------------

REAL FUNCTION MySIN(x)


IMPLICIT NONE
REAL, INTENT(IN) :: x

MySIN = SIN(DegreeToRadian(x))
END FUNCTION MySIN

! --------------------------------------------------------------------
! FUNCTION MySIN():
! This function takes a REAL argument in degree and computes its
! cosine value. It does the computation by converting its argument to
! radian and uses Fortran's cos().
! --------------------------------------------------------------------

REAL FUNCTION MyCOS(x)


IMPLICIT NONE
REAL, INTENT(IN) :: x

MyCOS = COS(DegreeToRadian(x))
END FUNCTION MyCOS

END MODULE MyTrigonometricFunctions

Click here to download this program.

Here is the main program:

! -----------------------------------------------------------------------

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/trigon.html (2 of 5)8/5/2006 8:10:55 PM


Trigonometric Functions Using Degree

! PROGRAM TrigonFunctTest:
! This program tests the functions in module MyTrigonometricFunctions.
! Module MyTrigonometricFunctions is stored in file trigon.f90.
! Functions in that module use degree rather than radian. This program
! displays the sin(x) and cos(x) values for x=-180, -170, ..., 0, 10, 20,
! 30, ..., 160, 170 and 180. Note that the sin() and cos() function
! in module MyTrigonometricFunctions are named MySIN(x) and MyCOS(x).
! -----------------------------------------------------------------------

PROGRAM TrigonFunctTest
USE MyTrigonometricFunctions ! use a module

IMPLICIT NONE

REAL :: Begin = -180.0 ! initial value


REAL :: Final = 180.0 ! final value
REAL :: Step = 10.0 ! step size
REAL :: x

WRITE(*,*) 'Value of PI = ', PI


WRITE(*,*)
x = Begin ! start with 180 degree
DO
IF (x > Final) EXIT ! if x > 180 degree, EXIT
WRITE(*,*) 'x = ', x, 'deg sin(x) = ', MySIN(x), &
' cos(x) = ', MyCOS(x)
x = x + Step ! advance x
END DO

END PROGRAM TrigonFunctTest

Click here to download this program.

Program Input and Output

The following is the output from the above program.

Value of PI = 3.1415925

x = -180.deg sin(x) = 8.742277657E-8 cos(x) = -1.


x = -170.deg sin(x) = -0.173648298 cos(x) = -0.98480773
x = -160.deg sin(x) = -0.342020214 cos(x) = -0.939692616
x = -150.deg sin(x) = -0.50000006 cos(x) = -0.866025388
x = -140.deg sin(x) = -0.642787635 cos(x) = -0.766044438
x = -130.deg sin(x) = -0.766044438 cos(x) = -0.642787635
x = -120.deg sin(x) = -0.866025388 cos(x) = -0.50000006
x = -110.deg sin(x) = -0.939692616 cos(x) = -0.342020124
x = -100.deg sin(x) = -0.98480773 cos(x) = -0.173648193
x = -90.deg sin(x) = -1. cos(x) = -4.371138829E-8

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/trigon.html (3 of 5)8/5/2006 8:10:55 PM


Trigonometric Functions Using Degree

x = -80.deg sin(x) = -0.98480773 cos(x) = 0.173648223


x = -70.deg sin(x) = -0.939692616 cos(x) = 0.342020154
x = -60.deg sin(x) = -0.866025448 cos(x) = 0.49999997
x = -50.deg sin(x) = -0.766044438 cos(x) = 0.642787635
x = -40.deg sin(x) = -0.642787576 cos(x) = 0.766044438
x = -30.deg sin(x) = -0.5 cos(x) = 0.866025388
x = -20.deg sin(x) = -0.342020124 cos(x) = 0.939692616
x = -10.deg sin(x) = -0.173648179 cos(x) = 0.98480773
x = 0.E+0deg sin(x) = 0.E+0 cos(x) = 1.
x = 10.deg sin(x) = 0.173648179 cos(x) = 0.98480773
x = 20.deg sin(x) = 0.342020124 cos(x) = 0.939692616
x = 30.deg sin(x) = 0.5 cos(x) = 0.866025388
x = 40.deg sin(x) = 0.642787576 cos(x) = 0.766044438
x = 50.deg sin(x) = 0.766044438 cos(x) = 0.642787635
x = 60.deg sin(x) = 0.866025448 cos(x) = 0.49999997
x = 70.deg sin(x) = 0.939692616 cos(x) = 0.342020154
x = 80.deg sin(x) = 0.98480773 cos(x) = 0.173648223
x = 90.deg sin(x) = 1. cos(x) = -4.371138829E-8
x = 100.deg sin(x) = 0.98480773 cos(x) = -0.173648193
x = 110.deg sin(x) = 0.939692616 cos(x) = -0.342020124
x = 120.deg sin(x) = 0.866025388 cos(x) = -0.50000006
x = 130.deg sin(x) = 0.766044438 cos(x) = -0.642787635
x = 140.deg sin(x) = 0.642787635 cos(x) = -0.766044438
x = 150.deg sin(x) = 0.50000006 cos(x) = -0.866025388
x = 160.deg sin(x) = 0.342020214 cos(x) = -0.939692616
x = 170.deg sin(x) = 0.173648298 cos(x) = -0.98480773
x = 180.deg sin(x) = -8.742277657E-8 cos(x) = -1.

Discussion

● Module MyTrigonometricFunctions defines four constants:


1. PI,
2. Degree180,
3. R_to_D for radian to degree conversion, and
4. D_to_R for degree to radian conversion.
● Module MyTrigonometricFunctions contains four functions:
1. RadianToDegree() converts its radian argument to degree;
2. DegreeToRadian() converts its degree argument to radian;
3. MySIN() takes a degree argument and returns its sine value; and
4. MyCOS() takes a degree argument and returns its cosine value.
● In the module, MySIN(x) first converts its degree argument x to radian using function DegreeToRadian() and
supplies the result to the Fortran SIN() function for computing the value of sine.
● The module uses MySIN() and MyCOS() rather than the same Fortran names SIN() and COS() to avoid confusion.
● As described in the use of modules, the main program can use variables, PARAMETERs and functions declared
and defined in a module. Thus, the main program can use the value of PARAMETER PI defined in module
MyTrigonometricFunctions. This is why there is no declaration of PI in the main program.
● In the main program, REAL variable x starts with 180 (in degree) and steps through 180 (in degree) with a step size
10. For each value of x, its SIN() and COS() is computed.
● If the main program and module MyTrigonometricFunctions are stored in files trigon.f90 and tri-test.f90,

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/trigon.html (4 of 5)8/5/2006 8:10:55 PM


Trigonometric Functions Using Degree

respectively, then you can compile them together with the following command:

f90 trigon.f90 tri-test.90

or with the following that generates an executable called tri-test:

f90 trigon.f90 tri-test.90 -o tri-test

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/trigon.html (5 of 5)8/5/2006 8:10:55 PM


A Little Privacy - PUBLIC/PRIVATE

A Little Privacy - PUBLIC/PRIVATE

All global entities of a module, by default, can be accessed by a program or another module using the USE statement. But,
it is possible to set some restrictions that some entities are private. A private entity of a module can only be accessed within
that module. On the other hand, one can explicitly list those entities that can be accessed from outside. This is done with the
PUBLIC and PRIVATE statements:

Syntax

The following is the syntax of a module:

PUBLIC :: name-1, name-2, ..., name-n

PRIVATE :: name-1, name-2, ..., name-n

All entities listed in PRIVATE will not be accessible from outside of the module and all entities listed in PUBLIC can be
accessed from outside of the module. All not listed entities, by default, can be accessed from outside of the module.

You can have many PRIVATE and PUBLIC statements.

In the following code segment, since VolumeOfDeathStar, SecretConstant and BlackKnight are listed in a statement,
they can only be used with the module. On the other hand, SkyWalker and Princess are listed in PUBLIC, they can be
accessed from outside of the module. There are entities not listed: function WeaponPower() and DeathStar. By default,
they are public and can be accessed from outside of the module.

MODULE TheForce
IMPLICIT NONE

INTEGER :: SkyWalker, Princess


REAL :: BlackKnight
LOGICAL :: DeathStar

REAL, PARAMETER :: SecretConstant = 0.123456

PUBLIC :: SkyWalker, Princess


PRIVATE :: VolumeOfDeathStar
PRIVATE :: SecretConstant, BlackKnight

CONTAINS
INTEGER FUNCTION VolumeOfDeathStar()
..........
END FUNCTION WolumeOfDeathStar

REAL FUNCTION WeaponPower(SomeWeapon)


..........
END FUNCTION

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/mod-private.html (1 of 4)8/5/2006 8:10:57 PM


A Little Privacy - PUBLIC/PRIVATE

..........
END MODULE TheForce

A Programming Example

In a previous example of using degree in trigonometric functions, four constants and four functions are defined. But, most
of them are used in and meaningful to the module MyTrigonometricFunctions. Thus, one can make them private so that
they cannot be accessed from outside of this module. Here is a rewritten version:

! --------------------------------------------------------------------
! MODULE MyTrigonometricFunctions:
! This module provides the following functions and constants
! (1) RadianToDegree() - converts its argument in radian to
! degree
! (2) DegreeToRadian() - converts its argument in degree to
! radian
! (3) MySIN() - compute the sine of its argument in
! degree
! (4) MyCOS() - compute the cosine of its argument
! in degree
! --------------------------------------------------------------------

MODULE MyTrigonometricFunctions
IMPLICIT NONE

REAL, PARAMETER :: PI = 3.1415926 ! some constants


REAL, PARAMETER :: Degree180 = 180.0
REAL, PARAMETER :: R_to_D = Degree180/PI
REAL, PARAMETER :: D_to_R = PI/Degree180

PRIVATE :: Degree180, R_to_D, D_to_R


PRIVATE :: RadianToDegree, DegreeToRadian
PUBLIC :: MySIN, MyCOS

CONTAINS

! --------------------------------------------------------------------
! FUNCTION RadianToDegree():
! This function takes a REAL argument in radian and converts it to
! the equivalent degree.
! --------------------------------------------------------------------

REAL FUNCTION RadianToDegree(Radian)


IMPLICIT NONE
REAL, INTENT(IN) :: Radian

RadianToDegree = Radian * R_to_D

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/mod-private.html (2 of 4)8/5/2006 8:10:57 PM


A Little Privacy - PUBLIC/PRIVATE

END FUNCTION RadianToDegree

! --------------------------------------------------------------------
! FUNCTION DegreeToRadian():
! This function takes a REAL argument in degree and converts it to
! the equivalent radian.
! --------------------------------------------------------------------

REAL FUNCTION DegreeToRadian(Degree)


IMPLICIT NONE
REAL, INTENT(IN) :: Degree

DegreeToRadian = Degree * D_to_R


END FUNCTION DegreeToRadian

! --------------------------------------------------------------------
! FUNCTION MySIN():
! This function takes a REAL argument in degree and computes its
! sine value. It does the computation by converting its argument to
! radian and uses Fortran's sin().
! --------------------------------------------------------------------

REAL FUNCTION MySIN(x)


IMPLICIT NONE
REAL, INTENT(IN) :: x

MySIN = SIN(DegreeToRadian(x))
END FUNCTION MySIN

! --------------------------------------------------------------------
! FUNCTION MySIN():
! This function takes a REAL argument in degree and computes its
! cosine value. It does the computation by converting its argument to
! radian and uses Fortran's cos().
! --------------------------------------------------------------------

REAL FUNCTION MyCOS(x)


IMPLICIT NONE
REAL, INTENT(IN) :: x

MyCOS = COS(DegreeToRadian(x))
END FUNCTION MyCOS

END MODULE MyTrigonometricFunctions

Click here to download this module. You also need a main program to test it. This mean program is identical to the one
used in a previous example. If you need it, click here to download a copy.

In this module, there are four PARAMETERs. Of these four, only PI is not listed as PRIVATE and hence can be accessed
from outside of this module. There are four internal functions, MySIN(), MyCOS(), RadianToDegree() and
DegreeToRadian(). The former two are listed as PUBLIC and can be accessed from outside of this module. The latter two

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/mod-private.html (3 of 4)8/5/2006 8:10:57 PM


A Little Privacy - PUBLIC/PRIVATE

are listed as PRIVATE and therefore cannot be accessed from outside of this module.

Note that if PI is also made PRIVATE, then the main program will have a mistake since it displays the value of PI:

PROGRAM TrigonFunctTest
USE MyTrigonometricFunctions

IMPLICIT NONE
..........
WRITE(*,*) 'Value of PI = ', PI ! PI cannot be used here
..........
END PROGRAM TrigonFunctTest

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/mod-private.html (4 of 4)8/5/2006 8:10:57 PM


Interface Blocks

Interface Blocks

All functions you have seen so far are internal functions that are contained in a program or a module. Functions that are not
contained in any program or modules are external functions. A program can use internal functions, external functions and
functions in modules. Moreover, external functions can be in the same file of the program or in several files.

External functions can be considered as program units that are independent of each other. Thus, the only way of
communication among external functions, the main program and modules is through arguments. In other words, from
outside of an external function, it is impossible to use its variables, PARAMETERs and internal functions.

For example, your main program could be in file prog4.f90. Your functions Area() and Test() are in file area.f90 and
functions ReadData() and DisplayResult() are in file InputOutput.f90. In this case, all four functions are external to the
main program. To compile this three-file program, you need the following command:

f90 prog4.f90 area.f90 InputOutput.f90

This will generate a a.out. Or, you can ask the Fortran compiler to generate an executable called prog4 with the following
command:

f90 prog4.f90 area.f90 InputOutput.f90 -o prog4

In addition to compiling these files, there is one more important thing. How does a function or a program know the way of
using a function? A function has a name, some arguments with certain types, and the type of the function value? Without
these information, a function might not be used correctly. To overcome this problem, an interface block is introduced. More
precisely, any external function to be used should be listed in an interface block along with the declaration of its
arguments and their types and the type of the function value.

Note that an external function can be in the file containing the main program or module. As long as that function is not
contained in any program, function, or module, it is external and an interface block is required in any program, function or
module where this function is used.

Syntax

The syntax of an interface block is the following:

INTERFACE
type FUNCTION name(arg-1, arg-2, ..., arg-n)
type, INTENT(IN) :: arg-1
type, INTENT(IN) :: arg-2
..........
type, INTENT(IN) :: arg-n
END FUNCTION name

....... other functions .......


END INTERFACE

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/interface.html (1 of 3)8/5/2006 8:10:58 PM


Interface Blocks

An interface block starts with the keyword INTERFACE and ends with END INTERFACE. For each external function to
be used in a program, module or a function, it should have an entry in an interface block. The information that should be
included are

1. the function header that contains the types of the function value, function name, and arguments,
2. the declaration of each argument, and
3. the END FUNCTION statement.

Note that only the types of argument and their INTENT are important. You can use other names for the arguments;
but, it would be a bad practice.

In fact, you can copy these information from that function's declarations to an interface block. For example, if there are two
external functions in a file as follows:

INTEGER FUNCTION Coin(value)


IMPLICIT NONE
INTEGER, INTENT(IN) :: value
...........
END FUNCTION Coin

REAL FUNCTION Volume(a, b, c)


IMPLICIT NONE
REAL, INTENT(IN) :: a, b, c
...........
END FUNCTION Volume

The corresponding interface block (if both functions are used) is

INTERFACE
INTEGER FUNCTION Coin(value)
INTEGER, INTENT(IN) :: value
END FUNCTION Coin

REAL FUNCTION Volume(a, b, c)


REAL, INTENT(IN) :: a, b, c
END FUNCTION Volume
END INTERFACE

If only function Volume() is used, one can just copy the information of Volume() to interface block as follows:

INTERFACE
REAL FUNCTION Volume(a, b, c)
REAL, INTENT(IN) :: a, b, c
END FUNCTION Volume
END INTERFACE

Where Does the Interface Block Go?

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/interface.html (2 of 3)8/5/2006 8:10:58 PM


Interface Blocks

The answer is simple. Put it after the IMPLICIT NONE statement. Thus, if the main program needs to use external
functions Coin() and Volume(), the following shows the place for the interface block:

PROGRAM CoinVolume
IMPLICIT NONE

INTERFACE
INTEGER FUNCTION Coin(value)
INTEGER, INTENT(IN) :: value
END FUNCTION Coin

REAL FUNCTION Volume(a, b, c)


REAL, INTENT(IN) :: a, b, c
END FUNCTION Volume
END INTERFACE

..... other specification statements .....


......... executable statements ..........
END PROGRAM CoinVolume

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/interface.html (3 of 3)8/5/2006 8:10:58 PM


Cm and Inch Conversion - Revisited

Cm and Inch Conversion - Revisited

Problem Statement

It is known that 1 cm is equal to 0.3937 inch and 1 inch is equal to 2.54 cm. Write a program that uses external functions to
convert 0, 0.5, 1, 1.5, ..., 8, 8.5, 9, 9.5, and 10 from cm to inch and from inch to cm. A version using internal functions can
be found in an earlier page.

Solution

The following solution has the main program and the two conversion functions in the same file. The order of placing these
functions and the main program in the file is unimportant.

! ---------------------------------------------------------------
! This program "contains" two REAL functions:
! (1) Cm_to_Inch() takes a real inch unit and converts
! it to cm unit, and
! (2) Inch_to_cm() takes a real cm unit and converts it
! to inch unit.
! The main program uses these functions to convert 0, 0.5, 1, 1.5,
! 2.0, 2.5, ..., 8.0, 8.5, 9.0, 9.5 and 10.0 inch (resp., cm) to
! cm (resp., inch).
! ---------------------------------------------------------------

PROGRAM Conversion
IMPLICIT NONE

INTERFACE
REAL FUNCTION Cm_to_Inch(cm)
REAL, INTENT(IN) :: cm
END FUNCTION Cm_to_Inch

REAL FUNCTION Inch_to_Cm(inch)


REAL, INTENT(IN) :: inch
END FUNCTION Inch_to_Cm
END INTERFACE

REAL, PARAMETER :: Initial = 0.0, Final = 10.0, Step = 0.5


REAL :: x

x = Initial
DO ! x = 0, 0.5, 1.0, ..., 9.0, 9.5, 10
IF (x > Final) EXIT
WRITE(*,*) x, 'cm = ', Cm_to_Inch(x), 'inch and ', &
x, 'inch = ', Inch_to_Cm(x), 'cm'

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/convert1.html (1 of 3)8/5/2006 8:11:00 PM


Cm and Inch Conversion - Revisited

x = x + Step
END DO

END PROGRAM Conversion

! ---------------------------------------------------------------
! REAL FUNCTION Cm_to_Inch()
! This function converts its real input in cm to inch.
! ---------------------------------------------------------------

REAL FUNCTION Cm_to_Inch(cm)


IMPLICIT NONE

REAL, INTENT(IN) :: cm
REAL, PARAMETER :: To_Inch = 0.3937 ! conversion factor

Cm_to_Inch = To_Inch * cm
END FUNCTION Cm_to_Inch

! ---------------------------------------------------------------
! REAL FUNCTION Inch_to_Cm()
! This function converts its real input in inch to cm.
! ---------------------------------------------------------------

REAL FUNCTION Inch_to_Cm(inch)


IMPLICIT NONE

REAL, INTENT(IN) :: inch


REAL, PARAMETER :: To_Cm = 2.54 ! conversion factor

Inch_to_Cm = To_Cm * inch


END FUNCTION Inch_to_Cm

Click here to download this program.

Program Input and Output

The following is the output from the above program.

0.E+0cm = 0.E+0inch and 0.E+0inch = 0.E+0cm


0.5cm = 0.196850002inch and 0.5inch = 1.26999998cm
1.cm = 0.393700004inch and 1.inch = 2.53999996cm
1.5cm = 0.590550005inch and 1.5inch = 3.80999994cm
2.cm = 0.787400007inch and 2.inch = 5.07999992cm
2.5cm = 0.984250009inch and 2.5inch = 6.3499999cm
3.cm = 1.18110001inch and 3.inch = 7.61999989cm
3.5cm = 1.37794995inch and 3.5inch = 8.88999939cm
4.cm = 1.57480001inch and 4.inch = 10.1599998cm
4.5cm = 1.77165008inch and 4.5inch = 11.4300003cm

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/convert1.html (2 of 3)8/5/2006 8:11:00 PM


Cm and Inch Conversion - Revisited

5.cm = 1.96850002inch and 5.inch = 12.6999998cm


5.5cm = 2.16534996inch and 5.5inch = 13.9699993cm
6.cm = 2.36220002inch and 6.inch = 15.2399998cm
6.5cm = 2.55905008inch and 6.5inch = 16.5100002cm
7.cm = 2.75589991inch and 7.inch = 17.7799988cm
7.5cm = 2.95274997inch and 7.5inch = 19.0499992cm
8.cm = 3.14960003inch and 8.inch = 20.3199997cm
8.5cm = 3.34645009inch and 8.5inch = 21.5900002cm
9.cm = 3.54330015inch and 9.inch = 22.8600006cm
9.5cm = 3.74014997inch and 9.5inch = 24.1299992cm
10.cm = 3.93700004inch and 10.inch = 25.3999996cm

Discussion

● External function Cm_to_Inch() converts its formal argument cm to inch, which is returned as the function value.
Please note that the constant 0.3937 is defined to be a PARAMETER.
● External function Inch_to_Cm() converts its formal argument inch to cm, which is returned as the function value.
Please note that the constant 2.54 is defined to be a PARAMETER.
● The main program uses DO-EXIT-END DO to generate 0, 0.5, 1, 1.5, ..., 8, 8.5, 9, 9.5 and 10. For each value,
Cm_to_Inch() and Inch_to_Cm() are called to perform conversion.
● To provide the main program with correct information of the two external functions, the following interface block is
inserted in the beginning of the main program:

INTERFACE
REAL FUNCTION Cm_to_Inch(cm)
REAL, INTENT(IN) :: cm
END FUNCTION Cm_to_Inch

REAL FUNCTION Inch_to_Cm(inch)


REAL, INTENT(IN) :: inch
END FUNCTION Inch_to_Cm
END INTERFACE

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/convert1.html (3 of 3)8/5/2006 8:11:00 PM


Heron's Formula for Computing Triangle Area Using External Functions

Heron's Formula for Computing Triangle Area Using


External Functions

Problem Statement

We have seen Heron's formula for computing triangle area using internal functions. This problem uses the same idea; but
the program should use external functions.

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:

In order for a, b and c to form a triangle, two conditions must be satisfied. First, all side lengths must be positive:

Second, the sum of any two side lengths must be greater than the third side length:

Write a program to read in three real values and use a function for testing the conditions and another function for computing
the area. Should the conditions fail, your program must keep asking the user to re-enter the input until the input form a
triangle. Then, the other function is used to compute the area.

Solution

! --------------------------------------------------------------------
! This program uses Heron's formula to compute the area of a
! triangle. It "contains" the following functions;
! (1) LOGICAL function TriangleTest() -
! this function has three real formal arguments and tests
! to see if they can form a triangle. If they do form a
! triangle, this function returns .TRUE.; otherwise, it
! returns .FALSE.

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/area-3.html (1 of 4)8/5/2006 8:11:02 PM


Heron's Formula for Computing Triangle Area Using External Functions

! (2) REAL function TriangleArea() -


! this functions has three real formal arguments considered
! as three sides of a triangle and returns the area of this
! triangle.
! --------------------------------------------------------------------

PROGRAM HeronFormula
IMPLICIT NONE

INTERFACE
LOGICAL FUNCTION TriangleTest(a, b, c)
REAL, INTENT(IN) :: a, b, c
END FUNCTION TriangleTest

REAL FUNCTION Area(a, b, c)


REAL, INTENT(IN) :: a, b, c
END FUNCTION Area
END INTERFACE

REAL :: a, b, c, TriangleArea

DO
WRITE(*,*) 'Three sides of a triangle please --> '
READ(*,*) a, b, c
WRITE(*,*) 'Input sides are ', a, b, c
IF (TriangleTest(a, b, c)) EXIT ! exit if not a triangle
WRITE(*,*) 'Your input CANNOT form a triangle. Try again'
END DO

TriangleArea = Area(a, b, c)
WRITE(*,*) 'Triangle area is ', TriangleArea

END PROGRAM HeronFormula

! --------------------------------------------------------------------
! LOGICAL FUNCTION TriangleTest() :
! This function receives three REAL numbers and tests if they form
! a triangle by testing:
! (1) all arguments must be positive, and
! (2) the sum of any two is greater than the third
! If the arguments form a triangle, this function returns .TRUE.;
! otherwise, it returns .FALSE.
! --------------------------------------------------------------------

LOGICAL FUNCTION TriangleTest(a, b, c)


IMPLICIT NONE

REAL, INTENT(IN) :: a, b, c
LOGICAL :: test1, test2

test1 = (a > 0.0) .AND. (b > 0.0) .AND. (c > 0.0)

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/area-3.html (2 of 4)8/5/2006 8:11:02 PM


Heron's Formula for Computing Triangle Area Using External Functions

test2 = (a + b > c) .AND. (a + c > b) .AND. (b + c > a)


TriangleTest = test1 .AND. test2 ! both must be .TRUE.
END FUNCTION TriangleTest

! --------------------------------------------------------------------
! REAL FUNCTION Area() :
! This function takes three real number that form a triangle, and
! computes and returns the area of this triangle using Heron's formula.
! --------------------------------------------------------------------

REAL FUNCTION Area(a, b, c)


IMPLICIT NONE

REAL, INTENT(IN) :: a, b, c
REAL :: s

s = (a + b + c) / 2.0
Area = SQRT(s*(s-a)*(s-b)*(s-c))
END FUNCTION Area

Click here to download this program.

Program Input and Output

The following is the output from the above program.

Three sides of a triangle please -->


-3.0 4.0 5.0
Input sides are -3., 4., 5.
Your input CANNOT form a triangle. Try again
Three sides of a triangle please -->
1.0 3.0 4.0
Input sides are 1., 3., 4.
Your input CANNOT form a triangle. Try again
Three sides of a triangle please -->
6.0 8.0 10.0
Input sides are 6., 8., 10.
Triangle area is 24.

Discussion

● External LOGICAL function TriangleTest() receives three REAL values. The result of the first test condition is
saved to a local LOGICAL variable test1, while the result of the second condition is saved to another LOGICAL
variable test2. Since both conditions must be true to have a triangle, test1 and test2 are .AND.ed and the result goes
into the function name so that it could be returned.
● External REAL function Area is simple and does not require further discussion.
● The main program has a DO-EXIT-END DO loop. In each iteration, it asks for three real values. These values are

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/area-3.html (3 of 4)8/5/2006 8:11:02 PM


Heron's Formula for Computing Triangle Area Using External Functions

sent to LOGICAL function TriangleTest() for testing. If the returned value is .TRUE., the input form a triangle
and the control of execution exits. Then, the area is computed with REAL function Area(). If the returned value is .
FALSE., a message is displayed and loops back asking for a new set of values.
● To provide the main program with all information for using the two external functions, an interface block is inserted
in the beginning:

INTERFACE
LOGICAL FUNCTION TriangleTest(a, b, c)
REAL, INTENT(IN) :: a, b, c
END FUNCTION TriangleTest

REAL FUNCTION Area(a, b, c)


REAL, INTENT(IN) :: a, b, c
END FUNCTION Area
END INTERFACE

http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap06/area-3.html (4 of 4)8/5/2006 8:11:02 PM

Você também pode gostar