Fortran: More


Following is further Fortran information not covered in the lessons.

More Intrinsic Functions

This table lists additional functions intrinsic to Fortran, not already listed in Lesson 1.

Function Description
aint(x) truncates the decimal part of x
(without changing the type of x)
anint(x) rounds x to the nearest integer
(without changing the type of x)
int(x) converts x to integer type, giving it
the value of the integer closest to x
but no larger than x in absolute value
log10(x) common logarithm of x (base 10)
max(x1,x2,...,xn) maximum of x1, x2, ..., xn
min(x1,x2,...,xn) minimum of x1, x2, ..., xn
nint(x) converts x to integer type,
rounding x to the nearest integer


This command, used in a subprogram, preserves the values of local variables (i.e., variables used in the subprogram but not listed in the title statement) from one call of the subprogram to the next. For instance, the statement

save m, z

in a subroutine ensures that in calls after the first run the subroutine remembers the final values of m and z from the previous run. A save statement by itself,
save    ,

preserves the values of all local variables in the subprogram. You cannot save a listed variable of the subprogram - the compiler will give an error message. (EG: If a subroutine's first line is "subroutine area(r)", then you cannot save r.)

Common (Blank)

Ordinarily the only information shared between the main program and subprograms are the values of variables appearing in variable lists. The common statement can be used to share additional information.
The simplest form of the common statement is the blank common statement. Let us suppose for illustration that the main program has real variables x and y as well as an integer variable n which are to be shared with one or more subroutines. Then at the beginning of the main program, before any executable statements, you first declare the types of x, y, and n and next insert the "blank common" statement
common x, y, n    .

This instructs Fortran to preserve three "common" memory locations for x, y, and n, designated as triangles below:
x → Δ
y → Δ
n → Δ

These memory locations are then accessible by all subroutines of the program containing a similar common statement (but with possibly different variables). For example, suppose a subroutine declares real variables u and v and an integer variable m. If the subroutine contains also the common statement
common u, v, m    ,

then u, v, and m will share memory locations with x, y, and n, respectively :
x → Δ ← u
y → Δ ← v
n → Δ ← m

When the values of u, v, and m change in the subroutine, then the values of x, y, and n in the main program change accordingly; and vice-versa - changes in x, y, or n in the main program produce changes in u, v, and m in the subroutine. Obviously, because of the sharing of memory locations, the types of x, y, and n must match those of u, v, and m, respectively (and also dimensions must match in the case of arrays.)
It is possible for a third or even more subroutines to share the same three memory locations. If a third subroutine has real variables a and b and an integer variable k, as well as the statement

common a, b, k    ,

then x, u, a share one memory location, y, v, b another, and n, m, k a third. A change in one of these variables in the main program or a subroutine produces the same change in whatever variables share the same memory location.
A common statement cannot list variables that are listed also in the title statement of the subprogram in which the common statement appears. (EG: If a subroutine's first line is "subroutine area(r)", then you cannot list r in the subroutine's common statement.)

Common (Named)

In programs with more than one subroutine it is sometimes desirable to share different sets of variables among different sets of program units. In such situations the named common statement is useful. The general form of this statement is

common / name1 / list1 / name2 / list2 / name3 / list3 / … / nameN / listN    .

The "names" are names for the different sets of variables, and the "lists" contain the names of variables in these sets.
Suppose, for example, that the main program uses variables A, B, C, D, E, F, G, while subroutine "demo1" uses variables A, B, C, D, and subroutine "demo2" uses variables C, D, E, F, G. If we want all program units using the same variable to share the value of that variable, then in the main program we insert the named common statement
common / first / A, B / second / C, D / third / E, F G     ,

in subroutine "demo 1" we insert
common / first / A, B / second / C, D    ,

and in "demo 2" we insert
common / second / C, D / third / E, F, G    .

Then the variable set "first" consists of A and B, and is shared by the main program and demo1. Variable set "second" consists of C and D and is shared by all three units. Variable set "third" consists of E, F, and G and is shared by the main program and "demo2". It is not necessary that different units use the same variable names for shared data. For example, subroutine "demo2" could name its five variables V, W, X, Y, Z; then its common statement would change to
common / second / V, W / third / X, Y, Z     ,

and consequently V and C would share a memory location, as would W and D, X and E, Y and F, and Z and G.


A data statement is used to initialize (i.e., assign initial values to) variables before the program begins. All data statements must appear after parameter and type declarations; it is common practice to include them immediately following these statements.
The general form of a data statement is
data list1 / data1 / list2 / data2 / list3 / data 3 / ... / listN / dataN /     .

Each list is a list of variables separated by commas, and each data is a list of values of the variables in the preceding list. Following is a table of examples with the corresponding resulting assignments:
data x, y, z / 2.1, 3.3, -4.4 / x = 2.1, y = 3.3, z = - 4.4
data k, m, n, p / 3 * 0, 1 / k = m = n = 0, p = 1
data first, last / "Jane", "Smith" / first = "Jane", last = "Smith"
data A / 5.2 / B, C / 2.8, 3.9 / A = 5.2, B = 2.8, C = 3.9
data x, y / 2*1. / m,n / 2*0 / pi / 3.14 / x = y = 1., m = n = 0, pi = 3.14

Note that in a data list the notation "n * x" means that the value x is to be assigned to n successive variables in the preceding variable list.
Data statements were necessary in earlier versions of Fortran, when the compiler did not automatically initialize variables; in more modern versions of Fortran they can usually be omitted without repercussions.

Arithmetic If

The arithmetic if statement has the form

if (expression) k, m, n     ,

where expression is some numeric expression that Fortran can evaluate, and k, m, n are integers representing labels of executable statements. If expression is negative, zero, or positive, then the program jumps to the statement labeled k, m, or n, respectively. As illustration, a program solving a quadratic equation
ax2 + bx + c = 0

might have the arithmetic if statement
if (b * b - 4 * a * c) 10, 20, 30    .

Then if the discriminant b2 - 4ac is negative, the program jumps to the statement labeled 10, if it is zero the jump is to label 20, and if positive to label 30.

Computed Go To

The computed go to statement has the form
go to (n1 , n2 , ..., nm) integer expression    ,

where n1, n2, ..., nm are integers representing labels of executable statements, and integer expression is some integer - valued expression that Fortran can evaluate. If the value of this expression is 1, the program jumps to the statement labeled n1, if the value is 2 the program jumps to the statement labeled n2, etc. For example, suppose a program contains the sequence
print *, "Enter the number of the task you want to perform:"
read *, n
go to (10,12,14,16,18,20) n

If the user enters 1, the program jumps to the statement labeled 10, if the user enters 2 it jumps to statement 12, if the user enters 3 it jumps to 14, etc. If the user errs and enters an integer different from 1, 2, 3, 4, 5, 6, Fortran defaults to the first statement listed, in this case statement 10.