Вы находитесь на странице: 1из 66

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)


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
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 not part of the statement.

A = 174.5 * Year &


! this is a comment line
+ Count / 100

The above is equivalent to the following, since the comment is 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 ThisIsALong and VariableName. In this way, a
token (name and number) can be split over two lines. However, this is not
recommended
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
 ' " ( ) * + - / : = _
 ! & $ ; < > % ? , .
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:
o Correct Examples: 0, -345, 768, +12345

o 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.
o 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 $
o 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
o 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)
o 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:
"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
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:
o MTU, MI, John, Count

o I, X

o I1025, a1b2C3, X9900g

o R2_D2, R2D2_, A__

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

o R2-D2: same as above

o 6feet: the first character must be a letter

o _System: same as above

 Use meaningful names


o Good names: Total, Rate, length

o 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.
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.
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:
o MTU, MI, John, Count

o I, X

o I1025, a1b2C3, X9900g

o R2_D2, R2D2_, A__

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

o R2-D2: same as above

o 6feet: the first character must be a letter

o _System: same as above

 Use meaningful names


o Good names: Total, Rate, length

o 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.
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:
o Correct Examples: 0, -345, 768, +12345

o 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.
o 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 $
o 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
o 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)
o 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:
"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 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,


o Name and Street are character variables that can hold a string of no more than 15
characters:
o CHARACTER(LEN=15) :: Name, Street
o FirstName, LastName and OtherName are character variables that can hold a
string of no more than 20 characters:
o 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,
o Name and Street are character variables that can hold a string of no more than 15
characters:
o CHARACTER(15) :: Name, Street
o FirstName, LastName and OtherName are character variables that can hold a
string of no more than 20 characters:
o 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 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.
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,


o Name and Street are character variables that can hold a string of no more than 15
characters:
o CHARACTER(LEN=15) :: Name, Street
o FirstName, LastName and OtherName are character variables that can hold a
string of no more than 20 characters:
o 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,
o Name and Street are character variables that can hold a string of no more than 15
characters:
o CHARACTER(15) :: Name, Street
o FirstName, LastName and OtherName are character variables that can hold a
string of no more than 20 characters:
o 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 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.
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. 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.
 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
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


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

If the input lines are

100 200 300 400


500 600 700 800
900
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

If the input lines are

100 200 300


400 500 600
700 800 900

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

== /= < <=
none
.AND. left to right
Logical
.NOT. .OR. left to right
right to
lefRelationa .EQV. .NEQV. left to right
l

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

REAL mixed mode REAL

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:

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

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

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.

More Complicated Examples:


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

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.
 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
 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 lef-hand side of =, although it can be used on the right-hand side. The
following is wrong!
INTEGER, PARAMETER :: InchToCM = 2.54, factor = 123.45
INTEGER :: X = 15

InchToCM = factor * X

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:
Function Meaning Arg. Type Return 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(x) arc cosine of x REAL REAL

ATAN(x) arc tangent of x REAL REAL

EXP(x) exp(x) REAL REAL


LOG(x) natural logarithm 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:

Function Meaning Arg. Type Return Type

INT(x) integer part x REAL INTEGER

NINT(x) nearest integer to x REAL INTEGER

FLOOR(x) greatest integer less than or equal to x REAL INTEGER

FRACTION(x) the fractional part of x REAL REAL

REAL(x) convert x to REAL INTEGER REAL

 Other functions:

Function Meaning Arg. Type Return Type

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

INTEGER INTEGER
MOD(x,y) remainder x - INT(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)
--> (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.
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

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

We have discussed the READ and WRITE statements. These are the so-called list-directed
input/output statements. They are also referred to as free-format input/output statements. List-
directed input/output statements are easy to use; however, we have no control over the
appearance of the input and output. To overcome this problem, we should use formats.

Fortran formats are used to control the appearance of the input and output. It has the following
simple form:

( ..... format edit descriptors ..... )


That is, a Fortran format is a pair of parenthesis that contains format edit descriptors separated by
commas.

There are three possible ways to prepare a Fortran format. Fortran has a FORMAT statement;
but, we will not use it because the two methods discussed below offer higher level of flexibility.

 Write the format as a character string and use it to replace the second asterisk in READ(*,*) or
WRITE(*,*).
 READ(*,'(2I5,F10.2)') ... variables ...
 READ(*,"(5F10.2)") ... variables ...

 WRITE(*,'(A,I5)') ... variable and expressions ...
 WRITE(*,"(10F5.2)") ... variable and expressions ...

The above has two READ and two WRITE statements whose second asterisks are replaced with
format character strings. 2I5, F10.2, 5F10.2, A,I5 and 10F5.2 are format edit descriptors.

 Since a format is a character string, we can declare a character constant to hold a format string.
 CHARACTER(LEN=20), PARAMETER :: FMT1 = "(I5,F10.2)"
 CHARACTER(LEN=*), PARAMETER :: FMT2 = "(4I5, 5E14.7, 8F5.0)"

 READ(*,FMT1) ... variables ...
 READ(*,FMT1) ... variables ...

 WRITE(*,FMT2) ... variables and expressions ...
 WRITE(*,FMT2) ... variables and expressions ...

In the above, character constants (defined as PARAMETERs) FMT1 and FMT2 are used as
formats.
 We can also use a character variable to hold a format. In the example below, the character
variable String is set to a format and used in READ and WRITE statements.
 CHARACTER(LEN=80) :: String

 String = "(3I5, 10F8.2)"

 READ(*,String) ... variables ...

 WRITE(*,String) ... variables and expressions ...

Note that the same format can be used in both READ and WRITE statements.

WARNING: The length of the string which contains a format must be large enough. Otherwise, the
format stored there becomes incomplete and causes format error. Consider the following
example.

CHARACTER(LEN=10) :: FMT

FMT = "(I2,F3.5,E15.7)"
WRITE(*,FMT) ......
Since FMT has length 10 and the format contains 15 characters, what FMT can actually have is

(I2,F3.5,E
which is not a complete format.

Format Edit Descriptors


The tedious part of using Fortran format is to master many format edit descriptors. Each edit descriptor
tells the system how to handle certain type of values or activity. Each value requires some positions. For
example, an integer of four digits requires at least four positions to print. Therefore, the number of
positions to be used is the most important information in an edit descriptor.

We shall use the following convention of symbols:

 w: the number of positions to be used


 m: the minimum number of positions to be used

 d: the number of digits to the right of the decimal point

 e: the number of digits in the exponent part

Although we may print a number using as many positions as you want, this is only for input/output. This
number of positions is not the precision (i.e., the number of significant digits) of that number. To be
more precisely, computers normally can store real numbers up to seven significant digits. This is the
precision of real numbers. However, we can print a real number using 50 positions in which 25 positions
are for the fraction part. This is only a way of describing the appearance and does not change the
precision of real numbers.

The following are the editor descriptors to be discussed. Details will be given on subsequent
pages.

Purpose Edit Descriptors

Reading/writing INTEGERs Iw Iw.m

Decimal form Fw.d

Exponential form Ew.d Ew.dEe


Reading/writing REALs
Scientific form ESw.d ESw.dEe

Engineering form ENw.d ENw.dEe

Reading/writing LOGICALs Lw

Reading/writing CHARACTERs A Aw

Horizontal nX

Positioning Tabbing Tc TLc and TRc

Vertical /

Grouping r(....)

Format Scanning Control :


Others
Sign Control S, SP and SS

Blank Control BN and BZ

Most edit descriptors can be repeated and several edit descriptors can be grouped into a group.
For most of the cases, edit descriptors are separated by commas. The following is an example:

CHARACTER(LEN=30) :: Format

Format = "(5X, I5.2, F10.3, A, ES14.7)"


READ(*,Format) ... variables ...

WRITE(*,Format) ... variables and expressions ...


In the above example, format Format has five edit descriptors 5X, I5.2, F10.3, A and ES14.7. Adjacent
edit descriptors are separated by a comma.

IMPORTANT: You can use both listed-directed and formatted READs and WRITEs in your program.
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
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 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 Smith becomes Smit and the original TEXAS
becomes TEXAS_, where _ indicates a space.
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.

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?


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

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


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


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

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

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

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


 LefHand(1:6) = "uvwxyz": the new content of LefHand is "uvwxyz7890".

 LefHand(:6) = "uvzxyz": the result is identical to the previous example.

 LefHand(4:) = "lmnopqr": the new content of LefHand is "123lmnopqr".

 LefHand(3:8) = "abc": the new content of LefHand is "12abc***90", where * denotes a space.
Note that since LefHand(3:8) consists of 6 character positions and "abc" has only three
characters, the remaining will be filled with spaces.

 LefHand(4:7) = "lmnopq": the new content of LefHand 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

! 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

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"
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 important to know when assigning a name to a string:


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"


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


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


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

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


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


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

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

Вам также может понравиться