3.1 Numeric Kind Parameterization

Next: 3.2 Precision Selection Up: 3 Numerical Robustness Previous: 3 Numerical Robustness

## 3.1 Numeric Kind Parameterization

The Fortran 90 KIND mechanism is a standardization, regularization, and generalization of the common ``*size" extension to Fortran 77. For example, though they are not standard, it is common for REAL*4 to be the same as single precision REAL and REAL*8 to be equivalent to DOUBLE PRECISION; the ``*size" syntax is a form of parameterization of the different kinds of real data types. Fortran 90 formalizes this concept of a type kind and associates an integer kind value with each intrinsic data type. These kind values are left implementation dependent (more about that in a minute), but if an implementation chooses the value 4 for single precision REAL and 8 for DOUBLE PRECISION, then alternative ways of specifying REAL are REAL(4) and REAL(KIND=4), and alternative ways of specifying DOUBLE PRECISION are REAL(8) and REAL(KIND=8). The complete formal syntax for the REAL type specifier in declaration statements is therefore:

`   REAL [([KIND= ] kind-value )]`

Though some implementations may choose kind values 4 for single precision real and 8 for double precision real, so that these numbers are similar to the common ``*4" and ``*8" extensions, or to represent the number of bytes in an object of this kind (the original motivation for the 4 and 8), this is not appropriate for all architectures. Some machines, for example (e.g., the Cray vector supercomputers), use a different (from 4) number of bytes for single precision real objects. Possibly more important, an implementation might support more than one form of single precision, one the default REAL and the other(s) using the same amount of storage but a different representation method. For example, on a machine whose native arithmetic is not IEEE, a Fortran implementation might support a second form of (single precision) real based upon IEEE arithmetic. In Fortran 90 terms, this would merely be another kind of real, with a different type kind value. There is therefore no ``obvious" set of kind values optimal for every implementation, which is the reason the kind values are left implementation dependent.

Fortunately there is a way to both isolate implementation kind value dependencies from application code and make the code more readable at the same time. That technique is to use the KIND intrinsic function to establish the correct values for (appropriately named) integer constants. (The KIND intrinsic returns the integer kind value for the type of its argument for that implementation.) For example, suppose that SINGLE and DOUBLE are the names of integer constants that have (somehow acquired) the proper kind value for single and double precision real, respectively. Then

```REAL(SINGLE)    ...single precision variables...
REAL(DOUBLE)    ...double precision variables...```
may be used to declare single and double precision real variables, as indicated. Alternatively, the ``full blown" syntax for such declarations is:
```REAL(KIND=SINGLE)    ...single precision variables...
REAL(KIND=DOUBLE)    ...double precision variables...```
Prior to their use in this way, SINGLE and DOUBLE have to be given the proper values, which may be accomplished with the following declaration:
```INTEGER, PARAMETER ::  SINGLE = KIND(1.0),                   &
DOUBLE = KIND(1D0)```
(This uses the ``entity oriented" declaration style of Fortran 90 which, in this case, condenses an INTEGER statement and a PARAMETER statement into one combined statement.) The first use of the KIND intrinsic function in the preceding example has a single precision real argument(1.0), so that the value it returns is the integer kind value for single precision real. The second instance of the KIND intrinsic has a double precision real argument (1D0), so it returns the integer kind value for double precision real. Programs that use this technique are portable, regardless of the kind values chosen by the implementation

Type COMPLEX uses the same KIND values as does type REAL-the complex kind is really the kind of the real/imaginary parts-and there is a complex kind for each real kind supported by the implementation. Thus

```COMPLEX(SINGLE)     ...single precision complex variables...
COMPLEX(DOUBLE)     ...double precision complex variables...```
is the best manner in which to declare complex objects.

Further, if the implementation's native arithmetic is not IEEE, but it supports an IEEE data type, the integer constant IEEE could be assigned the kind value specified by the implementation for IEEE arithmetic. Then IEEE variables could be declared with:

```REAL(IEEE)          ...real variables of  type  IEEE ...
COMPLEX(IEEE)       ...complex variables  of type IEEE...```

Next: 3.2 Precision Selection Up: 3 Numerical Robustness Previous: 3 Numerical Robustness

verena@csep1.phy.ornl.gov