Relational Operators
Relational operators are binary and the result is logical (true or false).
Fortran 77 syntax & Fortran 90 syntax & Meaning
.lt. < less than
.le. <= less than or equal to
.eq. == equal to
.ge. >= greater than or equal to
.gt. > greater than
.ne. /= not equal to
Here is a Fortran example illustrating the relational operators:
program relational_operators
implicit none
integer :: i1,i2
real :: r1,r2
double precision :: d1,d2
complex :: cplx1,cplx2
character(len=50) :: ch1
character(len=12) :: ch2
NAMELIST /inputs/ i1,i2,r1,r2,d1,d2,cplx1,cplx2, ch1, ch2
! Read input values from a namelist called relational_operators.nml
open(unit=1, file='relational_operators.nml',status='old')
READ(unit=1,NML=inputs)
close(unit=1)
! write namelist to standard output
write(*,NML=inputs)
! relational operators:
! For integers
write(*,*) 'i1 < i2 ', i1 .lt. i2, i1 < i2
write(*,*) 'i1 <= i2 ', i1 .le. i2, i1 <= i2
write(*,*) 'i1 > i2 ', i1 .gt. i2, i1 > i2
write(*,*) 'i1 >= i2 ', i1 .ge. i2, i1>=i2
write(*,*) 'i1 == i2 ', i1 .eq. i2, i1==i2
write(*,*) 'i1 /= i2 ', i1 .ne. i2, i1/=i2
write(*,*)
! For real and integers
! when mixing reals and integer, integers are first converted to reals
write(*,*) 'r1 < i2 ', r1 .lt. i2, r1 < i2
write(*,*) 'i1 <= r2 ', i1 .le. r2, i1 <= r2
write(*,*) 'r1 > i2 ', r1 .gt. i2, r1 > i2
write(*,*) 'i1 >= r2 ', i1 .ge. r2, i1>=r2
write(*,*) 'r1 == i2 ', r1 .eq. i2, r1==i2
write(*,*) 'r1 /= r2 ', r1 .ne. r2, r1/=r2
write(*,*)
! COMPLEX values can only use == and /=
write(*,*) 'cplx1 == cplx2 ', cplx1 .eq. cplx2, cplx1==cplx2
write(*,*) 'cplx1 /= cplx2 ', cplx1 .ne. cplx2, cplx1/=cplx2
write(*,*)
! CHARACTERS can only be compared with CHARACTERS
write(*,*) 'ch1 < ch2 ', ch1 .lt. ch2, ch1 < ch2
write(*,*) 'ch1 <= ch2 ', ch1 .le. ch2, ch1 <= ch2
write(*,*) 'ch1 > ch2 ', ch1 .gt. ch2, ch1 > ch2
write(*,*) 'ch1 >= ch2 ', ch1 .ge. ch2, ch1>=ch2
write(*,*) 'ch1 == ch2 ', ch1 .eq. ch2, ch1==ch2
write(*,*) 'ch1 /= ch2 ', ch1 .ne. ch2, ch1/=ch2
end program relational_operators
with the corresponding namelist input:
&INPUTS
i1=10,
i1=100,
r1=5.789,
r1=46.3983,
d1=4.56794325453674d0,
d1=1.9435456454765d1,
cplx1=(5.35,6.7),
cplx2=(1.98,4.2),
ch1='Hello world',
ch2='HELLO WORLD',
/
Logical Operators
.NOT. Logical Negation
.AND. Logical Conjunction
.OR. Logical Inclusive Disjunction
.EQV. Logical Equivalence
.NEQV. Logical Nonequivalence
program logical_operators
implicit none
INTEGER, PARAMETER :: rk = SELECTED_REAL_KIND(6,37)
real(kind=rk) :: temperature
logical :: good_data
logical :: user_quality_flag
! Read temperature from user
write(*,*) 'Enter temperature in degrees celsius'
read(*,*) temperature
! We asked user for quality control
write(*,*) 'A temperature of ', temperature, &
' degrees Celsius is realistic in January in Oslo (Enter T or F) '
read(*,*) user_quality_flag
! Quality control: combination of data checks and user quality flag
! Here we trust users...
WRITE(*,*) 'Good data? (T if good, F is bad) ', &
((temperature > -50) .AND. &
(temperature < 20) .AND. &
user_quality_flag)
end program logical_operators
IF and IF-THEN-ELSE Statements
IF (logical-expression-1) THEN
statement sequence 1
ELSE IF (logical expression 2) THEN
(logical-expression-2)
statement seqence 2
ELSE IF (logical-expression-3) THEN
statement sequence 3
ELSE IF (.....) THEN
...........
ELSE
statement sequence ELSE
END IF
Logical expressions are evaluated sequentially (i.e., top-
down). The statement sequence that corresponds to the
expression evaluated to .TRUE. will be executed.
Otherwise, the ELSE sequence is executed.
program if_and_logical_operators
implicit none
INTEGER, PARAMETER :: rk = SELECTED_REAL_KIND(6,37)
real(kind=rk) :: salinity
! Read salinity value in ppt from user
write(*,*) 'Enter salinity in ppt'
read(*,*) salinity
! Classification according to the salinity value
IF (SALINITY .LT. 0.) THEN
WRITE(*,*) 'INVALID SALINITY VALUE'
ELSE IF (SALINITY .LT. 0.5) THEN
WRITE(*,*) 'FRESHWATER'
ELSE IF (SALINITY .LT. 30) THEN
WRITE(*,*) 'BRACKFISH WATER'
ELSE IF (SALINITY .LT. 50) THEN
WRITE(*,*) 'SALINE WATER'
ELSE
WRITE(*,*) 'BRINE WATER'
ENDIF
end program if_and_logical_operators
IF-THEN-ELSE can be nested.
The SELECT CASE Statement
SELECT CASE (selector)
CASE (label-list-1)
statements-1
CASE (label-list-2)
statements-2
CASE (label-list-3)
statements-3
...
CASE (label-list-n)
statements-n
CASE DEFAULT
statements-DEFAULT
END SELECT
- selector is an expression evaluated
to an INTEGER, LOGICAL or
CHARACTER value.
YOU CANNOT USE REAL (try to find out why...)!
- label-list is a set of constants or
PARAMETERS of the same type as the selector
- statements is one or more
executable statements
program selectCase
implicit none
integer :: month, ndays, year
logical :: leap_year
print*, 'Enter a year'
read*, year
print*, 'Enter a month Enter a month (1-12)'
read*, month
if( ((year/4*4 .eq. year) .and. &
(year/100*100 .ne. year)) .or. &
(year/400*400 .eq. year) ) then
leap_year = .true.
else
leap_year = .false.
end if
select case(month)
case(4,6,9,11)
ndays = 30
case(1,3,5,7:8,10,12)
ndays = 31
case(2)
!----------------------------------
fevrier: select case(leap_year)
case(.true.)
ndays = 29
case(.false.)
ndays = 28
end select fevrier
!-----------------------------------
case DEFAULT
print*, 'Invalid month'
end select
print*, "There are ", ndays, " days in this month."
end program selectCase
DO loops
The counting DO loop
DO control-var = initial, final [, step]
statements
END DO
- control-var is an INTEGER variable
- initial, final and step are INTEGER expressions;
- Note, the value of step cannot be zero.
- If step is omitted, its default value is 1.
- If step is positive, this DO counts up; if step is
negative, this DO counts down
Here is a simple example to print odd values only:
program odd_number
implicit none
integer :: N, k
! odd integers between 0 & N
PRINT*, 'Enter an integer N: '
READ(*,*) N
WRITE(*,*) "Odd number between 0 and ", N
DO k = 1, N, 2
WRITE(*,*) k
END DO
end program odd_number
General DO-Loop with EXIT
DO
statements
END DO
- statements will be executed repeatedly.
- To exit the DO-loop, use the EXIT or CYCLE
statement.
- The EXIT statement brings the flow of control to
the statement following (i.e., exiting) the END DO.
- The CYCLE statement starts the next iteration
(i.e., executing statements again).
Same example as before but with EXIT and CYCLE statement.
program odd_number
implicit none
integer :: N, k
! odd integers between 0 & N
PRINT*, 'Enter an integer N'
READ(*,*) N
WRITE(*,*) 'Odd number between 0 and ', N
k = 0
DO
k = k + 1
if (k > N) EXIT
if (mod(k,2) .eq. 0) CYCLE
WRITE(*,*) k, ' is an odd number between 0 and ', N
END DO
end program odd_number