- Created by Unknown User (jorghe), last modified on 30.07.2019
You are viewing an old version of this page. View the current version.
Compare with Current View Page History
« Previous Version 4 Next »
This page contains a number of clarifications and explanations that will hopefully help you get a better understanding of Fortran
"Implicit none"
The line 'implicit none' is needed in Fortran to avoid obscure errors when defining variables. In earlier Fortran versions all variables were implicitly given as floats (real) unless the first letter in the name between i and n. 'implicit none' makes sure all variables have to be given-type explicit. Remember to add this line to every program, function and sub-routine. It is a very common form of error.
Subroutine vs. function
The difference between a subroutine and a function can be confusing, as they often can be implemented in similar ways to do the same job. The biggest difference is that subroutines work as pass-by-reference, while functions are pass-by-value. Se the example below for clarity. Many prefer subroutines because of its simpler syntax. Functions has a few syntax requirements. As you see inn the example under the function has to be defined with correct return type (this case float number).
In this example we will compare the implementation of subroutines vs. functions.
program main implicit none real :: a,b, fn !Notice how the function has to be defined as real a = 1.0 b = 1.0 print *, 'a befor subroutine: ', a call sub(a) print *, 'a after subroutine: ', a print *, 'b befor function: ', b print *, 'Result from function', fn(b), ', b after function: ', b end program
As you may notice we run functions on a "traditional" maner, while subroutines require the command "call".
The implementation of the subroutine is pretty straight forward:
subroutine sub(a) implicit none real :: a a = 2.0*a end subroutine sub
function fn(b) result (c) !Defining c as a return variable implicit none real, intent(in) :: b !Many compilers require input variables to have intent(in) real :: c c = 2.0*b end function fn
Intent(in) is telling the compiler that b is an un-changeable variable.
If your run this script you will get following output:
a befor subroutine: 1.0000000 a after subroutine: 2.0000000 b befor function: 1.0000000 Result from function 2.0000000 , b after function: 1.0000000 Press ENTER to continue--
Recursive functions
In Fortran subroutines and functions that does a recursive call on itself needs to be labeled "recursive function" in its declaration. It's easy to forget when handling programs that intuitively doesn't look like a recursive function. For an example see the calculator application. Below is a simple program for writing the Fibonacci numbers.
program main implicit none integer :: i, n, fib n = 12 do 10 i=1,n !10 is the label for the do loop print *, fib(i) 10 continue !Terminate loop with label 10 end program
recursive function fib(n) result (x) implicit none integer, intent(in) :: n integer :: x if (n<=1) then x = n else x = fib(n-2) + fib(n-1) end if end function fib
Higher precision
Standard precision for real numbers in FORTRAN i 6 decimal places. For some application or if you are dividing by very small numbers higher precision is needed to avoid numerical error. As shown in the example below we first create a new kind for real numbers (with precision set to 12 decimals). Then create real variables with the new kind we made.
subroutine hp_division() implicit none integer, parameter :: ikind=selected_real_kind(p=12) real(kind=ikind) :: a,b,res print *, 'Enter two numbers to divide' read *, a,b res = a/b print *, 'Result: ', res end subroutine hp_division
- No labels