SS 4068 Fortran Programming
SS 4068 Fortran Programming
C. H. Patterson
Hilary Term 2008
Recommended text:
Computing for Scientists: Principles of Programming with Fortran 90 and C++
Barlow and Barnett
Variables and Operators
Data Structure
Control
Subprograms: Functions and Subroutines
Characters and Strings
Pointers
Input and Output
Chapter 2 Variables and Operators
Fortran Programme Syntax
Programmes begin with the PROGRAM statement e.g.
PROGRAM HELLO_WORLD
Programmes end with
STOP
END
Programme statements begin in the 7th column and end without a semicolon in the 72nd column
There is usually only one statement per line but f90 statements on the same line can be separated by ;
Lines are continued with & in the 6th column of the following line
In f90 the comment symbol is ! It replaces // in C
! THIS IS A COMMENT
Variable names can be up to 31 characters in length
Begin with a letter
Not case sensitive
There are no reserved words
Write to screen with the PRINT statement
PRINT *, x
writes the variable x to the screen. * is otherwise the unit number of the file to be written to.
Read from Keyboard with the READ statement
READ *, y
Reads variable y from the keyboard.
Variable Declaration
Fortran allows for variables to be used without declaration and uses the convention that variables with names beginning a-h or o-z are REAL variables while those beginning with i-n are INTEGER. This language feature can be disabled by typing
IMPLICIT NONE
after the PROGRAM statement. This avoids many possible programme bugs. Variables are declared in C++ and f90 by separating variables from the variable type as follows:
float x_data;
REAL :: x_data
int mindex;INTEGER:: height
Variables can be initialised at the same time as they are declared
Floaty_data = 0.3;REAL
:: y_data = 0.3
In C++ there are short, int and long integer variable types. In Fortran the KIND distinguishes them. (See next section).
In f90 attributes of variables are specified after the variable type
INTEGER, PARAMETER :: m = 100 ! m is a parameter, value 100
Note position of ::
In order to declare an array which is to be dynamically allocated, it is declared with the attribute ALLOCATABLE
REAL, DIMENSION(:), ALLOCATABLE :: zdata
READ *,n
ALLOCATE (zdata(1:n))
READ *, (zdata(i),i=1,n)
DEALLOCATE(zdata)
The code above declares a 1D, allocatable array with name zdata. The value of the dimension is read in the second line, the array is allocated in the third and values of array elements are read in the fourth. After use the array is deallocated. Note round brackets for array indices rather than square brackets in C++.
In C++ floating point numbers come in types float and double. In f90 the equivalents are REAL (which we have already met) and DOUBLE PRECISION. To create a double precision constant, the assigned value must end with the D form for the exponent.
DOUBLE PRECISION :: two_thirds_d = 0.666666666666666D0
Type conversion
It is frequently necessary to convert between variable types, e.g. from an integer to a double in C++. In f90 these conversions are achieved as follows:
intjmin;
INTEGER :: jmax
floatxmin;
REAL
:: xmax
xmin = float(jmin);
xmax = REAL(jmax)
Operators
A list of operators and their precedence in f90 and in C++ is given on pp 47 and 48 in Tables 2.5 and 2.6 of BB.
Operations such as addition, subtraction, multiplication and addition have the same symbols in f90 and C++. However, there is no incrementation operator (i++) nor += operation to replace x = x + 1 in f90, as there is in C++.
Exponentiation in f90 is achieved with a double asterisk **.
AREA = PI * R**2
Logical operators in f90 include == (logical equals) /= (logical not equals) < (less than) (greater than) and >= (greater than or equals).
Exercise 1. Write a programme to read in a REAL and a DOUBLE PRECISION variable, add them as DOUBLE PRECISION variables and WRITE them to screen.
Chapter 3 Data Structure
Data Type: Integer
In C++ there are long, short, and signed, unsigned integer types besides the usual int integer type. int is a 2 byte, signed integer and ranges from -32768 to 32767 but this can vary on some machines and with some compilers. long int (or simply long) integer variables are 4 byte integer variables and range from -2147483648 to 2146483647. unsigned short integer variables also contain 2 bytes and range from 0 to 65535. See Table 3.1 on p58 BB.
In f90 the number of bytes to be used is determined by the KIND attribute. The function SELECTED_INT_KIND(n) gives the KIND parameter for integers large enough to represent n decimal digits. Here is an example of the use of this function together with the KIND parameter.
INTEGER, PARAMETER:: large = SELECTED_INT_KIND(9)
INTEGER, PARAMETER:: small = SELECTED_INT_KIND(5)
INTEGER (KIND = small):: my_salary
INTEGER (KIND = large):: your_salary
Note KIND is not an attribute and so is separated by () rather than , before ::.
Data Type: Float and Real
Single precision floating point numbers are stored in 4 bytes as
Number = mantissa . 2exponent
The mantissa is a number between 1 and 2 and the exponent lies between -127 and +128 so that the range of numbers that can be represented is 2-127 to 2+128. In base 10 the range of numbers that can be represented in this way is
5.9 E-39 to 3.4 E+38
Here the notation E means 10 to the power of. The smallest change (1 bit) is 2-24 (6.0E-08) which means that single precision numbers have roughly 7 significant figures.
Double precision floating point numbers are stored in 8 bytes. The mantissa occupies 53 bits and the exponent 11 bits.
In f90 these variables are declared as DOUBLE PRECISION. More variation in the precision can be obtained using the SELECTED_KIND_REAL(n,m) function. This returns the KIND value required to store numbers with n decimal digits of precision in the range Em. Currently many systems use KIND=1,2 for the two precisions.
The following code illustrates the use of these functions here.
INTEGER, PARAMETER:: dble = SELECTED_REAL_KIND(15,300)
REAL(KIND = dble)
:: BIG1! Approved
REAL(dble)
:: BIG2! Also OK
DOUBLE PRECISION:: BIG3! Alternative
The KIND of a real number is found using KIND(x). e.g.
single = KIND(0.0E0)
double = KIND(0.0D0)
Note that D and E notations in exponent indicate double and single precision numbers.
The function xdouble = REAL(x,KIND=double) allows for conversion between different real data types.
In C++ the equivalents are float, double and long double. The precision of the long double type is compiler and machine dependent.
Data Type: Complex
In f90 a complex number can be represented by specifying the real and imaginary parts or using the function CMPLX. Everything pertinent to real number representations also applies (twice) to the complex data type. The following piece of code illustrates declaration and use of the complex data type.
COMPLEX
:: z1, i = (0., 1.)
COMPLEX(KIND(0.D0))
:: z2
z1 = CMPLX(2.0,3.5)
! z1 = 2 + 3.5 i
arg_z1 = ATAN2(AIMAG(z1),REAL(z1))! angle of z1
z2 = i**i
! = exp(-pi/2) = 0.2078796
PRINT, * AIMAG(z2)
! expect 0.0 in this case
Data Type: Logical
In f90 there is a LOGICAL data type used in conjunction with Boolean algebra for decision making. These variables can take the values .TRUE. or .FALSE. (note the periods beginning and ending these values). In C++ there is a data type bool which is the equivalent to the LOGICAL data type. Operators for LOGICAL variables are given in Table 2.5 p47 of BB. The code example below checks whether a number lies between 10 and 20.
INTEGER
:: n
LOGICAL
:: LARGE_ENOUGH
LOGICAL
:: SMALL_ENOUGH
LOGICAL
:: VALID
PRINT *,Enter a value for n which lies between 10 and 20
READ *,n
LARGE_ENOUGH = (n>=10)
SMALL_ENOUGH=(n = == != (/= in f90). f90 also recognises relational operators of f77.
.LT. .GT. .LE. .GE. .EQ. .NE.
For example
if (i < 3> && (j >=4) statement
IF (i > 3) .AND. (j >=4) statement
If statement runs to more than one line then statement is enclosed in {} (C++) or is replaced by THEN with statements on following lines and terminated by ENDIF (f90).
IF (i > 3) .AND. (j >=4) THEN
DO THIS
DO THAT
ENDIF
See ch4_1.f and ch4_2.f for illustration.
The compound IF-ELSE statement allows more than one distinct conditions to be tested.
if (dev < tol)
IF (dev < tol) THEN !condition TRUE
cout | / \ ~ + - = # % & ^ * _
Converting characters to integers
ACHAR(n) n INTEGER
returns CHARACTER
character corresponding to n in ASCII character set
CHAR(n) n INTEGER
returns CHARACTER
character corresponding to n in your system's character set
IACHAR(c) c CHARACTER returns INTEGER
integer corresponding to c in ASCII character set
ICHAR(c) c CHARACTER returns INTEGER
integer corresponding to c in ASCII character set
Strings of several characters
A continuous collection of characters is known as a string, for example, 'Hello World' (including the space) is a string. C++ uses double quotes to enclose strings whereas f90 uses single quotes.
#include
cout reply ;
CASE('N'); query = .False.
switch (toupper(reply))
CASE('n');query = .False.
{case 'Y' :
CASE DEFAULT
return 1;
PRINT *, ' Sorry?', &
case 'N' :
& ' Please reply Y or N'
return 0;
CYCLE
}
END SELECT
cout
Top Related