The rules for
real2 = integer + real1converts 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) resultit 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, str3we 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 assignmentFor 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) + vector2the 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 INTERFACEand 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_typeDefined 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 assignmentThe 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_EXPONENTLike all FORTRAN 77 functions (SIN, ABS, etc.), except LEN, these are array valued for array arguments (i.e. are elemental).