Professional Documents
Culture Documents
Tutorial FORTRAN 1
Tutorial FORTRAN 1
Professor
Department of Computer Science
Michigan Technological University
o Fortran Basics
o Fortran Control Structures
o Fortran Subprograms
o Fortran Arrays
Program Structure
Your program should have the following form:
PROGRAM program-name
IMPLICIT NONE
[specification part]
[execution part]
[subprogram part]
END PROGRAM program-name
Fortran Comments
Comments should be used liberally to improve readability. The following are the rules for
making comments:
PROGRAM TestComment1
..........
READ(*,*) Year ! read in the value of Year
..........
Year = Year + 1 ! add 1 to Year
..........
END PROGRAM TestComment1
PROGRAM TestComment3
..........
READ(*,*) Count
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.
The above is equivalent to the following, since the comment is ignored by the compiler:
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,
is equivalent to
Note that there are spaces between ThisIsALong and VariableName. In this way, a token
(name and number) can be split over two lines. However, this is not recommended
FORTRAN ALPHABETS
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
' " ( ) * + - / : = _
! & $ ; < > % ? , .
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.
If single quote is used in a string, then double quotes should be used to enclose the string:
"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.
o Correct Examples:
'What''s this?': content = What's this? and length = 11
'''''': content = '' and length = 2
o Incorrect Examples:
'Tech's seminar': the single quote between h and s should be written twice.
FORTRAN IDENTIFIERS
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.
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:
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:
Types INTEGER and REAL are easy. The following are examples:
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:
Here, variables letter and digit can 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 City and BOX can hold a string of no more than 10 characters, Nation can hold a string of
no more than 20 characters, and bug can 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 Title and Position are unknown and will be determined elsewhere.
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"
o 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"
o CHARACTER(LEN=4), PARAMETER :: Name = 'Smith'
o If the string is shorter, spaces will be added to the right. Since the string "LA" is of length 2 while
the name City is of length 4, two spaces will be padded to the right and the content of City
becomes "LA "
o 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"
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:
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:
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. The use of 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.
The following example initializes variables State1 to "MI", State2 to "MN", and State3 to "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.
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.
** right to left
+ - left to right
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
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.
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.
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:
o if the next one is lower, evaluate the current operator with its operands
o 3 * 5 - 4
In the above expression, in the left to right scan, operator * is encountered first. Since the the
operator - is lower, 3 * 5 is evaluated first transforming the given expression to 15 - 4. Hence, the
result is 11.
o 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).
o if the next one is higher than the current, the scan should continue with the next operator. For
example, consider the following expression:
o 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 ** 3 is 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)).
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
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.
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.
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:
o if the operands of this operator are of the same type, compute the result of this operator.
o 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 3.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.
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
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.
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.
o 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.
o 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.
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.
Radius = 5
Area = (Radius ** 2) * PI
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.
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!
InchToCM = factor * X
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:
INTEGER INTEGER
ABS(x) absolute value of x
REAL REAL
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:
Other functions:
INTEGER INTEGER
MAX(x1, x2, ..., xn) maximum of x1, x2, ... xn
REAL REAL
INTEGER INTEGER
MIN(x1, x2, ..., xn) minimum of x1, x2, ... xn
REAL REAL
FUNCTIONS IN AN EXPRESSION:
AN EXAMPLE :
The example below has three initialized variables A, B and C. The result is computed and saved
into uninitialized variable R.
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 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
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.
CHARACTER(LEN=5) :: Name
REAL :: height, length
INTEGER :: count, MaxLength
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 READ statements are used to read the following input lines,
100 200
300 400 500
600
then I, J, K, L, M and N will 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
Variables I, J and K receive 100, 200 and 300, respectively. Since the second READ starts with a new line,
L, M and N receive 500, 600 and 700, respectively. 400 on the first input line is lost. The next READ will
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
The first READ reads 100 and 200 into P and Q and 300 is lost. The second READ starts with a new input
line, which is the second one. It does not read in anything. The third READ starts with the third line and
reads 700 and 800 into R and 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.
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:
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.
INTEGER :: Factor, N
REAL :: 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
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
Angle = 20.0
Distance = 1350.0
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.
PROGRAMMING EXAMPLE: THREE PROGRAMMING TRAPS
PROBLEM STATEMENT
The purpose of this program is to show you three common programming traps:
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'
PROGRAM OUTPUT
First, the exponential trap:
2 ** 2 ** 3 = 256
( 2 ** 2 ) **3 = 64
2 ** ( 2 ** 3 ) = 256
4 / 6 = 0
REAL( 4 ) / 6 = 0.666666687
4 / REAL( 6 ) = 0.666666687
DISCUSSION
On the second line, it is easily seen that the original Smith becomes Smit and the original TEXAS becomes TEXAS_,
where _ indicates a space.
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
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)
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.
PROBLEM STATEMENT
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
d = SQRT(b*b - 4.0*a*c)
WRITE(*,*)
WRITE(*,*) 'Roots are ', root1, ' and ', root2
PROGRAM OUTPUT
A, B, C Please :
1.0 -5.0 3.0
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 Return key. Then, these values are stored in a, b and 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.
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
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
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.
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
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.
! --------------------------------------------------------------------
PROGRAM Projectile
IMPLICIT NONE
REAL, PARAMETER :: g = 9.8 ! acceleration due to gravity
REAL, PARAMETER :: PI = 3.1415926 ! you knew this. didn't you
PROGRAM OUTPUT
If the input to the program consists of the following three real values:
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.
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.
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".
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:
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
Year = DateINFO(1:4)
Month = DateINFO(5:6)
Day = DateINFO(7:8)
Hour = TimeINFO(1:2)
Minute = TimeINFO(3:4)
Second = TimeINFO(5:10)
WRITE(*,*)
WRITE(*,*) 'Time Information -> ', TimeINFO
WRITE(*,*) ' Hour -> ', Hour
WRITE(*,*) ' Minite -> ', Minute
WRITE(*,*) ' Second -> ', Second
WRITE(*,*) ' Pretty Time -> ', PrettyTime
WRITE(*,*)
WRITE(*,*) ' Pretty Time -> ', PrettyTime
PROGRAM OUTPUT
Date information -> 19970811
Year -> 1997
Month -> 08
Day -> 11
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"