Com221 Prac
Com221 Prac
Plato is a "programming environment". Within Plato, you can create and edit programs and get
them to run. Plato's editor is special – it understands the syntax of various programming
languages. We tell Plato which language we are using when we create our empty file and save it
with a .f95 (FORTRAN 95) extension. Provided you have given your file the appropriate extension,
Plato's editor will be able to check the syntax of the program, highlighting the various keywords
that it knows about using a colour code to distinguish between the various elements of the
language.
Always ensure that your program files have a .f95 extension
Running your first FORTRAN 95 Program
Page 1 of 19
Exercise 1.1
Type in the following exactly as shown:
!My first program
program first
print *,'This is my first program'
end program first
Page 2 of 19
answer=x+y !f:
arithmetic
print *, 'The total is ', answer !g: output
end program sum !h: end of
program
Page 3 of 19
program bug
this program is full of errors
real :: a,b,c
a = b + c
read *,c
print *,a
end program simple
The compiler will report two error messages when it attempts to compile. Click on
the details button. Each error generates a message.
Double clicking on the message will
take you to the line in the program where the fault occurs
To the user of the program, this is not at all obvious – they may have thought that the
program has crashed!
Type in a number then press enter
The program returns an strange value. This is an "execution time" error.
We need to find out what the warning message was. Click the "compile" button (to the left
of the ►). Then click the "details" button. Plato will tell you that the variable b has not been
given a value.
Correct the program to give b a value, and then execute the program again.
There is still a problem. This time, it is a problem with the program's logic.
Need a Hint?
The program statements are executed sequentially.
a = b + c
read *, c
print *, a
The statement
a = b + c
doesn't make sense, as at this stage of the program, we haven't yet given a value to c.
Important points to note
There are two types of errors associated with this program: compiler errors and run-
time errors.
Page 4 of 19
The program is also user-unfriendly. The program waits for input without telling the user
what is needed.
Fix the run time error by:
read in a value for b
correct the order of the statements
make the program more user-friendly,
then compare your program with the one called bugfixed.f95 in the downloads directory.
When the character variable is declared, we show the maximum length that the string can
occupy by following the name by a * then its maximum length. The example below has a
maximum length of 10 characters allowed for a person's name – this might not always be enough!
You have to make a judgement here.
program convert
!This example shows the use of integer and character variables
implicit none
integer :: pounds,pence,total
character :: name*10
print *,'What is your name?'
read *,name
print *, 'Hi ',name,'! Enter number of pounds and pence'
read *, pounds,pence
total =100 * pounds + pence
print *,'the total money in pence is ',total
end program convert
NOTE: Notice the inclusion of the line:
implicit none
By including it in your program, FORTRAN will check that you have properly declared all your
variable types. In the bad old days of programming, declaration of variables was thought to be
unnecessary and the old FORTRAN compilers used an implicit convention that integers have
names starting with the letters in the range i – n, all the others being real. FORTRAN still allows
you to do this if we don't include the line, implicit none. Time has shown that one of the
commonest reasons for error in a program is the incorrect use of variables.
Always use implicit none at the start of every program.
Exercise 1.4
With the program convert in section 1.5 as a guide, write a program to test out everything you've
learned so far. You might include different types of variables, for example real, integer,
and character. Include input and output using read and print. An example might be a program
that asks people questions, including things like their age and name and so on. It could, for
Page 5 of 19
example, print out their year of birth with a suitable message. It's up to you, just use your
imagination.
Saving the contents of Output Window
Run your last program again. When the black output window opens right click on the Plato icon in
the top left corner
Click on edit
Click Select all
Click copy
Open a new document in Word or Notepad and click paste.
Page 6 of 19
SECTION 2
MAKING DECISIONS
Aims
By the end of this worksheet, you will be able to:
Do arithmetic
Start to use FORTRAN intrinsic functions
Begin to understand program flow and logic
Know how to test for zero – important!
Learn more about good programming style
Assignment Statements
When we start programming, the similarity between mathematical equations and FORTRAN
statements can be confusing.
Consider the following FORTRAN statements:
x = 2 Store the value 2 in memory location x
y = 3 Store the value 3 in memory location y
z = x + y Add the values stored in memory location
x and y and store the result
in memory location z
In mathematics, “x = 2” means that the variable x is equal to 2. In FORTRAN it means “store the
value 2 in the memory location that we have given the name x”.
The significance of this is made clearer by the following equation in mathematics:
x + y =z
In mathematics, this means that the left hand side of the equation is equal to the right hand side.
In FORTRAN, this expression is meaningless: there is no memory location "x+y" and so it would
lead to a compiler error.
Rule – there can only ever be ONE variable name on the left hand side of an equals sign
Exercise 2.1
Write a program which reads in two numbers a and b. Get the program to swap the values around
so that the value that was in a is now in b, and print out the result. Hint you need to declare a third
variable for intermediate storage of the data. (Check your program by examining
program swap.f95 at Downloads
Arithmetic
The arithmetic operators are
+,- plus and minus
*,/ multiply and divide
** exponentiation (raise to the power)
() brackets
The order of precedence in FORTRAN is identical to that of mathematics.
Unlike algebra, the operator must always be present xy is not the same as x*y
Where operations are of equal precedence they are evaluated left to right
Consecutive exponentiations are evaluated right to left
We can override the order of evaluation by use of brackets
Exercise 2.2
The following program is an example of the use of arithmetic.
program calculate
implicit none
! a simple calculator
real :: x,y,z,answer
x=1.5
y=2.5
z=3.5
answer=x+y/z
print *,'result is ',answer
Page 7 of 19
end program calculate
Explore the use of arithmetic operators by modifying program calculate. Use it to calculate the
values:
Intrinsic Functions
FORTRAN is especially useful for mathematical computation because of its rich library of inbuilt
functions (intrinsic functions). We shall mention a few briefly here:
function type of type of
Definition
name argument result
sin(x) real real sine
cos(x) real real cosine
tan(x) real real tangent
atan(x) real real arctangent
absolute
abs(x) real/integer real/integer
value
sqrt(x) real real square root
exp(x) real real ex
log10(x) real real log10x
Trigonometric functions are calculated in radians (1 radian = 180/Pi degrees).
There are, of course, many more, and this list doesn't cover all FORTRAN variable types. The
following example shows the use of some of the inbuilt functions.
program trig
implicit none
real :: a,pi
print *,'Enter an angle between 0 and 90'
read *, a
pi = 4.0*atan(1.0)
print *,'the sine of ',a,' is ',sin(a*pi/180)
end program trig
Making Decisions
So far, our programs have worked as little more than basic calculators. The power of programming
comes in when we have to make decisions. Copy the example program, test.f95, to your own file
space. See if you can understand what is going on.
program test
implicit none
!use of a simple menu
real :: x,y,answer
integer :: choice
!set up the menu – the user may enter 1, 2 or 3
print *,'Choose an option'
Page 8 of 19
print *,'1 Multiply'
print *,'2 Divide'
print *,'3 Add'
read *,choice
x=3.4
y=2.9
!the following line has 2 consecutive
!equals signs – (no spaces in between)
if (choice == 1) then
answer=x*y
print *,'result = ',answer
end if
if (choice == 2) then
answer=x/y
print *,'result = ',answer
end if
if (choice == 3) then
answer=x+y
print *,'result = ',answer
end if
end program test
The highlighted lines in the above program are called if … end if statements. They work like this:
if (condition is true) then
execute this line
and this
and so on until we get to …
end if
It follows that if the condition is NOT true then the code 'jumps' to the next statement following the
'end if'. The statements between the if and the end if are deliberately indented, this makes the
program easier to read.
We use two consecutive equals signs (no space in the middle) to test for equality.
Compare:
Exercise 2.3
Examine program test above. The line:
print *,'result = ',answer
is repeated several times. Is this a good idea? Can you modify the program to make it more
efficient?
Program Style
A good program:
Uses comments appropriately to explain what is happening.
Uses indentation to make the program easier to read.
Uses meaningful variable names.
Uses sensible prompts to let the user know what is going on.
Uses implicit none at the start of every program.
Is efficient!
Page 9 of 19
If you want to get maximum marks for your assignments keep the above points firmly in mind. It is
not enough just to get a program to work!
More on decision making
In our test.f95 above, there was a problem if the user entered a value that wasn't catered for by
the program.
What happens if the user doesn't enter one of the values 1, 2 or 3?
We are going to look at a new structure, called if, else, endif that handles this situation. Examine
the following code snippet:
if (choice = = 1) then
do something
else if (choice = =2) then
do something else
else
do this if nothing else satisfies the conditions
end if
end if
Exercise 2.4
Write a program that reads a number from the keyboard. Get the program to decide whether:
the value of the number is greater than 0 but less than 1
or is greater than 1 but less than 10
or is outside of both these ranges
Print out a suitable message to inform the user.
The simple if statement
There is a simpler, one line form of the if statement. Say we just wanted to print out a simple
message such as
Page 10 of 19
print *, 'enter a positive number'
read *, num
if (num <0) stop
if (num < 10) print *, 'less than 10'
if (num > 10) print *, 'greater than 10'
print *,'It is a positive number'
This snippet also introduces a useful, simple statement stop – it simply stops the program.
Important note – testing for zero
Make sure you understand this !
Suppose that you wish to test whether a real variable is zero. The test
if (x == 0) then ….
is not a satisfactory test. Although integer numbers are held exactly by the
computer, real numbers are not.
The way around this is to test if the absolute value of the variable is less than some small
predefined value. For example:
if (abs(x) < .000001) then
print *,’No zero values! Please enter another
number’
read *, x
end if
Page 11 of 19
SECTION 3
LOOPS
AIMS
By the end of this worksheet, you will be able to:
Understand more about the use of real and integer variables and how to use a
mixture of data types in expressions
Understand how to re-use code by looping
Know how to control the number of times a section of code is executed by using a do
loop
Mixing variable types
Exercise 3.1
Copy divide.f95 from Downloads
Make sure you understand the following program thoroughly!
program divide
implicit none
integer :: x
real :: y
x = 1
y = x/3
print *, y
end program divide
Run it. This program produces the following output:
0.00000
Something odd is happening. The problem is the line:
y=x/3
FORTRAN evaluates the right hand side of the assignment first using integer arithmetic,
because both x and 3 are integer. 1 divided by 3 cannot be stored as an integer, and so the value
0 is returned. The result, 0, is then converted to a real number and the assigned to y.
Replace the line in program divide
x = 1
by
x = 10
Your output should now be:
3.00000
Can you see what is happening? FORTRAN is keeping the integer part of the answer and
throwing the rest away.
To get over this problem, we have to signal to FORTRAN that we want it to calculate the right
hand side of the expression using real arithmetic. If we want to keep x as integer data type, we
could re-write our expression as follows:
y=x/3.0
The presence of a real number on the right hand side causes the right hand side of the expression
to be evaluated using floating point arithmetic.
Actually, the problem is even more complicated! Where we have an expression like
y=x * ((2**i)/3)
where x and y are real and i is integer, FORTRAN computes the result in stages:
First it calculates (2**i)/3 and evaluates it as an integer number, then multiplies the result by x and
evaluates it as real.
Exercise 3.2
Copy check.f95 to your filestore.
program check
Page 12 of 19
!Integer and real arithmetic
implicit none
real :: x,y
integer i
x=2.0
i=2
y=x*((2**i)/3)
print *,y
y=x*((2.0**i)/3)
print *,y
end program check
… and examine its output. Make sure you understand why this is happening.
The do loop
Unless we are able to re-execute code, we might as well use a calculator… Now we start to take
advantage of the power of the computer.
Exercise 3.3
Copy program loop.f95
program loop
implicit none
integer :: i
do i=0,20
print *,i
end do
end program loop
do i = 5,-5,-2
Exercise 3.4
Using a do loop to generate integer values of x between –10 and 10 in steps of 1, write a program
that constructs a table of values of
y = 1.0/x
What happened when x had the value zero? Use an if, end if to test for the condition that gives
the incorrect value, and print out an appropriate message. Compare your result with divbyzero.f95.
Division by zero
is one of the commonest reasons for a program to fail
Nested Do Loops
Page 13 of 19
We want to construct a table of values for z where
z = xy
for values of x in the range 1 to 2 in steps of 0.5 and
y in the range 1 to 2 in steps of 0.5
Work through the next exercise which illustrates this:
Exercise 3.5
Copy program xytab.f95 to your filespace.
program xytab
implicit none
!constructs a table of z=x/y for values of x from 1 to 2
and
!y from 1 to 4 in steps of .5
real :: x, y, z
print *, ' x y z'
do x = 1,2
do y = 1,4,0.5
z = x/y
print *, x,y,z
end do
end do
end program xytab
Examine its output. Notice the use of the first print to give a heading to the table.
Using loops to do summation
Earlier on, we discussed the idea of assignments.
x = 1.0
means store the value 1.0 in the memory location called x.
If we had the following code:
x = 1.0
x = x + 1.0
print *, x
means “add 1.0 to the value currently stored in memory location x and then store the result
in memory location x”.
Exercise 3.6
Copy file increment.f95 to your file space and examine its output.
program increment
implicit none
integer :: i
real :: x
x = 1.0
do i=1,10
x = x + 1.0
print *, i,x
end do
end program increment
Page 14 of 19
Note carefully that we have set the initial value of x outside of the do loop. Why have we
done this? If you aren't sure – change the code to put the line x = 1.0 inside the loop – then
examine the output.
It is important to understand that if we use constructions such as x = x + 1.0, then it is vital
to initialise x to some value. If we don't, it is possible that the value might be set
to any random number. Run the program, make a note of the final value of x then put an
exclamation mark in front of the x = 1.0 statement and run the program again.
Exercise 3.7
Edit the line x = x + 1.0 in program increment.f95, and change it to x = x * i. Re-run the program
and examine the output. What is significant mathematically about the sequence of numbers that
has been generated?
Page 15 of 19
SECTION 4
FILES AND PRECISION
AIMS
By the end of this worksheet, you will be able to:
Read from and write to files
Use extended precision
Reading from files
In the real world, most of the data we use for our programs will be kept in files. We just need a
modification to the read statement that we are already familiar with to do this.
This program reads 3 numbers from a file called 'mydata.txt' into an array. Use
Windows Notepad to create such a file for yourself, or copy the file from mydata.txt which is on
the website.
program readdata
implicit none
!reads data from a file called mydata.txt
real :: x,y,z
open(10,file='mydata.txt')
read(10,*) x,y,z
print *,x,y,z
end program readdata
The new material here are the lines
open(10,file='mydata.txt')
read(10,*) x,y,z
The open statement links the file called 'mydata.txt' with an input device numbered 10 (it
doesn't have to be 10, it could be any positive integer). To read from device 10, we just use it as
the first argument in the read statement.
Exercise 4.1
Use Notepad to create a file called evenodd.txt. In the file type 10 numbers, one per line. Write a
program that reads data from evenodd.txt one line at a time. Check if each number is even or odd
and print out a suitable message. One way to check if a number is even or odd is to use
the mod intrinsic function, like this…
if (mod(num,2)>0) then……
mod returns the remainder of the first argument divided by the second. If the return value is
greater than zero, then the number must be odd. Check program evenodd.f95 to see if you are
correct.
Writing to files
This is a similar idea to reading from files. We need a new statement, though, instead of print, we
use write.
program io2
!illustrates writing arrays to files
implicit none
real :: num
integer :: i
open(12,file='myoutput')
do i = 1,100
num = i/3.0
write(12,*) num
end do
print *, 'finished'
end program io2
Exercise 4.2
Write a program which reads in numbers from a file one at a time. If the number is positive, it
should store it in a file called 'positive.txt' and negative numbers in a file called 'negative.txt'.
Page 16 of 19
Extending the precision
So far, we have used two types of variables, real and integer. The problem so far, as you will
have noticed on output, is that we are extremely limited by the number of significant digits that are
available for computation. Clearly, when we are dealing with iterative processes, this will lead
rapidly to errors. We can, however, extend the precision available from the single
precision default, which gives us 6 figure decimal precision to 15 figures by using a new
specification for real numbers.
program extended
implicit none
integer, parameter :: ikind=selected_real_kind(p=15)
real (kind=ikind) :: sum,x
integer :: i
sum=0.0
do i=1,100
x=i
sum = sum + 1.0/(x**6)
end do
print *, sum
end program extended
Page 17 of 19
val=10.0_ikind/3 !extend precision constant - right!
print*,val
val=10.0/3.0 !real constants - wrong!
print*,val
val = .12345678901234567890 !real constants - wrong!
print *, val
val = .12345678901234567890_ikind !ext precision consts - right!
print *, val
end program extendedconstants
You should run this program for yourself and think carefully about its implications. This program
demonstrates how easy it is to get calculations wrong. I’ll leave this to you to experiment to
ensure that you fully understand the importance of properly declaring variables and the use of
constants in FORTRAN programming. A systematic approach to your programming will reduce the
risk of errors as will running programs with test data that have known solutions so that you can
confirm that your program is error free.
Magnitude limitations
We have already observed that there is a limitation of the accuracy with which we can do
calculations in FORTRAN (and indeed, any, computer language). There are also limitations on the
magnitude of a number. The various magnitude and precision limits are summarized in the
following table:
Exercise 5.3
To illustrate these limits copy file magnitude.f95 and run the program. Take a while to get a feel
for what is going on. Try inputting various values for the variable maxpower (eg 400). Can you
confirm that the table above is correct?
One interesting construct is
print *,i,2.0_ikind**i
Here, we are telling the compiler that the real constant 2.0 is also using extended precision. Check
what happens if you select extended precision (option 3) and enter a value of maxpower of 400.
See what happens if you rewrite the line to be
print *,i,2.0**i
Run the program again and enter the same values. Can you explain what is going on?
Convergence – exiting loops on a condition
In the program extended.f95, we found the sum of
It is useful to determine at what point such sums converge to a steady value – otherwise we may
make arbitrary assumptions about the summation range. Clearly, a point will be reached, within
the precision range that can be handled on our computer, that the term
Page 18 of 19
will be too small to contribute to the sum. At this point we should exit the loop otherwise the
program will do more computation than is required.
One way to do this is to compare the value of the variable sum with its previous value, and if the
difference between the two is very small, then exit the loop.
program whileloop
implicit none
integer, parameter :: ikind=selected_real_kind(p=15)
real (kind=ikind) :: sum,previoussum,x,smallnumber,error
integer :: i
sum = 0.0
previoussum = 0.0
smallnumber = 10.0_ikind**(-15.0)
do i=1,1000
x=i
sum = sum + 1.0 /(x**6)
error=abs(sum-previoussum)
if (error<smallnumber) then
print *,'sum ',sum,' number of loops ',i
exit
end if
previoussum = sum
end do
end program whileloop
IMPORTANT NOTE
In the real world, we have to make choices about the amount of precision we need to work
to. It is pointless asking for 15 digits of precision if, for example, we can only take a
measurement to + or – 1% accuracy!
It is not necessary to always use a loop counter in a do loop. If we don't actually specify a
counter, the program will loop forever. Constructs like this are OK:
smallnumber = .0000001_ikind
do
print *, 'enter a positive number '
read *, number
if (number <= smallnumber) exit
end do
The disadvantage is that, if you get the code wrong, you run the risk of the program looping
forever – generally it's safer to use a loop counter!
Page 19 of 19