Notes Fortran 5

Math 60 -- D. C. Smolarski, S.J.
Santa Clara University, Department of Mathematics

[Return to Math 60 Homepage | Return to Notes Listing Page]

Contents


Character Variables [EF 13]

Unlike in C++, strings of characters may be stored, in Fortran, in variables that are, functionally, NOT arrays.

DECLARATION [EF 13.1]

        CHARACTER*n  variable_list
or, in Fortran-90/95/2003
        CHARACTER (LEN=n)  :: variable_list
where n is the number of characters in each variable.

EXAMPLE

        CHARACTER*20 NAME
        CHARACTER*3  PETE, FRED, SAM*5
==> NAME can store 20 characters.
==> PETE and SAM can each store 3 characters.
==> SAM can store 5 characters (note the legal alternative way of specifying the number of characters that SAM can store).

ASSIGNMENTS [EF 13.2]

Enclose a character string in single quotes. For example,

        PETE = 'Sam'
        SAM = 'Patty'

Character I/O [EF 13.3]

Format field descriptor:
        An       A stands for "alphanumeric"
                 n is the number of characters to be outputted
                   in that variable
For example,
          PETE = 'SAM'
          SAM = 'DENIS'
          WRITE(6,10) PETE, SAM
          10  FORMAT (1X, A3, 2X, A5)
No quotes are needed for FORMATTED input:
        PROGRAM TEST113
        CHARACTER*5 A,B
        READ(5, 101) A,B
        101  FORMAT(2A5)
        WRITE(6,102) B,A
        102  FORMAT(1X, 2A5)
        STOP
        END
Input line:
     1 2 3 4 5 6 7 8 9 10 
     N O W   I S   T H E
Output:
     0 1 2 3 4 5 6 7 8 9 10 11


Thus we see that
     A <=== __ __ __ __ __

     B <=== __ __ __ __ __

Special Numeric Types [EF 14]

Double Precision [EF 14.1]

Declaration
        DOUBLE PRECISION A, B, C
This corresponds to type double in C/C++.

Constants

Use scientific notation with a D instead of an E. For example, double precision zero is

        0.0D00

I/O

Use the D field descriptor in FORMAT statements. It work the same as the E descriptor.

NOTE

On the HP "math" server, REAL variables have about 7 places accuracy, while DOUBLE PRECISION variables have about 16 places. Even though one may request 20 digits (places) to be printed out with a REAL variable, ONLY the first 7 places have any meaning!

Complex [EF 14.2]

DECLARATION
        COMPLEX A, B, C
CONSTANTS

To use a complex constant value in an expression, one uses two REAL numbers in parentheses, i.e., a = 3.0 + 4.0i is rendered as

        A = (3.0,4.0)
CONVERSION LIBRARY FUNCTIONS [EF 14.3]

Fortran includes library conversion functions such as CMPLX, AIMAG, REAL, CONJG.

I/O

For each complex variable, one uses 2 F (or E) descriptors, or one can split the complex number value into two temporary real numbers and print them out individually as REAL numbers.


8

Extended Numeric Precision and KIND [EF 14.4]

Besides REAL and DOUBLE PRECISION (sometimes indicated by REAL*8), some versions of Fortran have (in the past) included a "quadruple precision" (a "double double"), often indicated by REAL*16. (The number after the * usually refers to the number of bytes used to store a number.)

One should note, however, that there is no industry wide standard as to the number of significant digits "real" or "double" corresponds to across different platforms. In other words, a "real" variable on one machine might correspond to 7 digits but 14 on a different machine.

Fortran 90 introduce a KIND attribute for variable which helps a user to specify the amount of precision desired. In this context the word KIND does not mean "gentle" or "merciful," but, rather, refers to similarities or differences (e.g., "They are two of a kind."). A character variable is a different "kind" of variable than an integer or a real number, and a single precision real variable is a different kind of a variable than a double precision variable.

KIND is a function which return a (system dependent) unique number distinguish one "kind" of variable from another when a constant value of that type of variable is given as the argument. E.g., KIND('a') may return a value of 1 on a specific system, whilc KIND(1) may return of value of 4. Since the values are different, we can say that a variable that can store 'a' and a variable that can store 1 are different kinds of variables.

There are two functions (which include "kind" as part of the name) which can help determine possible "kinds" of variable.

SELECTED_REAL_KIND(i,j) will specify a value corresponding to the desired number of digits accuracy (in i) and the desired maximum exponent (in j). The actual value returned is secondary to the possibility of using a value (if one is returned) to declare real variables of this "kind."

Similarly SELECTED_INT_KIND(i) will specify a value corresponding to the desired number of digits accuracy (in i). This value can be used to declare integer variables of this "kind."

NOTE that not every possible precision is implemented by every compiler on every platform! For integer numbers, if the desired kind is not available, SELECTED_INT_KIND will return an "error" value of -1. For real numbers, if the desired kind is not availabe, SELECTED_REAL_KIND will return an "error" value of -1 if sufficient precision is unavailable, -2 if sufficient exponent range is not available, and -3 if both are unavailable.

The follow are examples of using these functions:

       INTEGER, PARAMETER     :: MYPREC20=SELECTED_REAL_KIND(20,350)
       REAL(KIND=MYPREC20)    :: X, Y, Z
       INTEGER, PARAMETER     :: MYPREC20=SELECTED_INT_KIND(10)
       INTEGER (KIND=MYPREC10):: I, J, K
Here, X, Y, Z are declared to have at least 20 significant digits and have exponents in the range -350 to 350. Similarly, I, J, K are declared to at at least 10 signficant digit accuracy.

One can also use this to "create" a new name for "double precision" and reference double precision constants differently (as an example). For example,

      INTEGER, PARAMETER  :: DP = KIND(0.0D0)
      REAL (KIND=DP)      :: X, Y, Z
      X = 123.45_DP
Note that the final underscore with "DP" after 123.45 indicates that 123.45 is to be considered the same "kind" of real variable as is X, Y, Z. (The older fashion would write this as 123.45D0.)

Some newer Fortran manuals suggest completely avoiding "double precision" and only using the "kind" designation for higher precision variable and values.

We also note that alternative "kinds" can be applied to other "types" of variables, such as character, and one can designate that a character string can be stored using a different encoding (such as Japanese Kanji) for the characters in the "alphabet."

Fortran 90/65/2003 Derived Types [EF 15.1]

Fortran 90 introduced the possibility of defining "record" variable types (similar to C++ classes or structs). In Fortran 90/95/2003 terminology, these are called "derived types." (The following example parallels the example in Math 10, Notes N14, in which a new datatype, called INFOLINE, is defined and then variables of that datatype are declared.)

DEFINITION [EF 15.2]

        TYPE INFOLINE
           CHARACTER (LEN = 30) :: NAME
           CHARACTER (LEN = 50) :: ADDRESS
           INTEGER :: ZIP
           INTEGER :: ACCNTNUM
        END TYPE INFOLINE
DECLARATION [EF 15.3]
        TYPE (INFOLINE) :: ACCOUNT, LIST(100), TEMP
USING COMPONENTS OF DERIVED TYPE VARIABLES [EF 15.4]

In general, the principles are the same as with C++ or Pascal, except that instead of using the period (dot), . , as a subdivider, one uses the percent sign, %. For example,

        ACCOUNT%ZIP
        LIST(1)%ACCNTNUM
DERIVED TYPES AND MODULES [EF 15.5]

For practicality, when defining a new derived type that may be used in several program segments (e.g., the main program and one or more functions or subroutines), it is easiest to place the type definition in a MODULE and invoke this module in each program segment.

Fortran 90/95/2003 SELECT Statement [EF 16.1]

Fortran 90 introduced a new statement corresponding to the switch statement of C++ (or the case of Pascal). Each option is a distinct alternative (as in Pascal) and, thus, there is no need for anything like the C++ break command. As an example,
        SELECT CASE (IVAR)
           CASE (1)
              CALL SUB1
           CASE (2:4)
              CALL SUB2
           CASE DEFAULT
              CALL SUB3
        END SELECT
NOTE: (1) IVAR in parentheses after SELECT CASE is the variable whose value will be tested against options listed in the alternatives;
(2) the second alternative shows how to list a range of consecutive values;
(3) each option is a mutually exclusive alternative (unlike C++).

Examples of Unstructured and Structured Fortran Code [EF 16.2]

An Unstructured Segment of Fortran (Old FORTRAN 66 Style)

        IF(K.EQ.1) GO TO 212
        IF(K.EQ.2) GO TO 18
        GO TO 106
  212   X(1) = 5.
        Y(K) = K+2.5
   32   IF(K*J.LE.4) GO TO 184
   30   L4 = K*J-K+1
        Y(L4) = 1.0
        X(L4) = Y(L4)
  210   IF(K-J.GE.7) GO TO 265
        GO TO 184
   18   X(K) = 6.
        Y(K) = K-1.5
        GO TO 32
  106   IF(K.NE.3) GO TO 10
        Y(K) = 0.0
        X(K) = Y(K)
        GO TO 23
  265   IF(K.GE.J+7) GO TO 10
        X(K-J+1) = 0.0
        Y(K-J+1) = 1.0
        GO TO 10
  184   IF(K*J.LE.4) GO TO 23
  180   L = K*J-2*K
        Y(L) = 0.0
        X(L) = Y(L)
   23   IF(K-J.GE.7) X(K-J+1) = 1.0
        IF(K*J.LE.4) GO TO 30
        GO TO 265
   10   IF(K-J.GE.7) Y(K-J+1) = 0.0

An Equivalent Segment of Fortran That is Structured (New Fortran 90 Style)

        SELECT CASE (K)
           CASE(1)
              X(1) = 5.0
              Y(K) = K+2.5
           CASE(2)
              X(K) = 6.
              Y(K) = K-1.5
           CASE(3)
              X(K) = 0.0
              Y(K) = 0.0
        END SELECT
        IF(K*J <= 4) THEN
              L4 = K*J-K+1
              X(L4) = 1.0
              Y(L4) = 1.0
           ELSE
              L = K*J-2*K
              X(L) = 0.0
              Y(L) = 0.0
        END IF
        IF(K-J >= 7) THEN
              X(K-J+1) = 1.0
              Y(K-J+1) = 0.0
           ELSE
              X(K-J+1) = 0.0
              Y(K-J+1) = 1.0
        END IF

Detecting the End-of-File [EF 3.11]

STYLE I

        READ (20, 101, END=200) A, B, ...
If the end-of-file is reached, the flow of the program jumps to the statement labeled (in this case) 200 and continues from there. For example,
        DO
           READ(20,101,END=200) A,B,C
           ...
        END DO
   200  CONTINUE

STYLE II

One can make use of the IOSTAT option in the READ statement.

One first needs to declare an INTEGER variable that will store the "status value" of the input file after a READ. If the value becomes -1, the end-of-file is reached. For example,

        INTEGER IO
        ...
        IO = 1
        DO WHILE (IO /= -1)
           READ(20,100,IOSTAT=IO) A,B
           ...
        END DO


9

This page is maintained by Dennis C. Smolarski, S.J. dsmolarski@math.scu.edu
© Copyright 1998, 1999, 2006 Dennis C. Smolarski, SJ, All rights reserved. Last changed: 23 January 2006. Minor correction: 2 February 2006.