The rules for
real2 = integer + real1
converts integer to a real value of the same kind as real1; the
result is of same kind, and is converted to the kind of real2
for assignment.
For
< <= == /= > >=
so we can write expressions such as
IF (a < b .AND. i /= j) THEN ! for numeric variables
flag = flag == semaphore ! for logical variables
In the case of
CHARACTER(8) result
it is now legal to write
result(3:5) = result(1:3) ! overlap allowed
result(3:3) = result(3:2) ! no assignment of null string
For an operation between
TYPE string
INTEGER length
CHARACTER(80) value
END TYPE string
CHARACTER char1, char2, char3
TYPE(string) str1, str2, str3
we can write
str3 = str1//str2 ! must define operation
str3 = str1.concat.str2 ! must dedine operation
char3 = char2//char3 ! intrinsic operator only
str3 = char1 ! must define assignment
For the first two cases, assignment applies on a
component-by-component basis (but can be overridden), and they
also require us to define the exact meaning of the // symbol.
We see here the use of an intrinsic symbol and of a
named operator, .concat. . A difference is that,
for an intrinsic operator token, the usual precedence rules apply,
whereas for named operators their precedence is the
highest as a unary operator or the lowest as a binary one. In
vector3 = matrix * vector1 + vector2
vector3 =(matrix .times. vector1) + vector2
the two expresions are equivalent only if appropriate parentheses
are added as shown.
In each case, we have to provide, in a module,
procedures defining the operator and
assignment, and make the association by an
interface block, also in the module (we shall return to this later).
For the moment, here is an example of an interface
for string concatenation
INTERFACE OPERATOR(//)
MODULE PROCEDURE string_concat
END INTERFACE
and an example of part of a module containing the definitions
of character-to-string and string-to-character assignment. The string
concatenation function was shown already in Part 1.
MODULE string_type
TYPE string
INTEGER length
CHARACTER(LEN=80) :: string_data
END TYPE string
INTERFACE ASSIGNMENT(=)
MODULE PROCEDURE c_to_s_assign, s_to_c_assign
END INTERFACE
INTERFACE OPERATOR(//)
MODULE PROCEDURE string_concat
END INTERFACE
CONTAINS
SUBROUTINE c_to_s_assign(s, c)
TYPE (string) :: s
CHARACTER(LEN=*) :: c
s%string_data = c
s%length = LEN(c)
END SUBROUTINE c_to_s_assign
SUBROUTINE s_to_c_assign(c, s)
TYPE (string) :: s
CHARACTER(LEN=*) :: c
c = s%string_data(1:s%length)
END SUBROUTINE s_to_c_assign
FUNCTION string_concat(s1, s2)
:
END FUNCTION string_concat
END MODULE string_type
Defined operators such as these are required for the expressions that are
allowed too in structure constructors (see Part 1):
str1 = string(2, char1//char2) ! structure constructor
So far we have discussed scalar variables. In the case of
REAL, DIMENSION(10, 20) :: a, b, c REAL, DIMENSION(5) :: v, w LOGICAL flag(10, 20)can write
a = b ! whole array assignment
c = a/b ! whole array division and assignment
c = 0. ! whole array assignment of scalar value
w = v + 1. ! whole array addition to scalar value
w = 5/v + a(1:5, 5) ! array division, and addition to section
flag = a==b ! whole array relational test and assignment
c(1:8, 5:10) = a(2:9, 5:10) + b(1:8, 15:20)
! array section addition and assignment
v(2:5) = v(1:4) ! overlapping section assignment
The order of expression evaluation
is not specified in order to allow for optimization
on parallel and vector machines. Of course, any
operators for arrays of derived type must be defined.
There are some new real intrinsic functions that are useful for numeric computations:
CEILING FLOOR MODULO (also integer)
EXPONENT FRACTION
NEAREST RRSPACING SPACING
SCALE SET_EXPONENT
Like all FORTRAN 77 functions (SIN, ABS, etc.), except LEN,
these are array valued for array arguments (i.e. are elemental).