J3/12-164r1
To: J3
From: Dan Nagle/Malcolm Cohen
Subject: Update Kinds Discussion in Annex
Date: 2012 June 28
The kinds discussion in the explanatory annex doesn't mention
iso_fortran_env and does mention using literal kind values. Thus,
there is room for improvement. Also no mention is made in the existing
text of kinds for derived types. This paper offers text that might be
an improvement on the existing text.
Edits:
[467:5-27] Replace subclause C.1.1 with the following.
C.1.1 Selecting kinds of intrinsic types (4.4)
For each of the intrinsic types (character, complex, integer, logical, and
real), there is the possibility of more than one approximation method or
representation method being available on a processor. Each approximation
method or representation method for a type is identified by a kind type
parameter value.
Kind type parameter values are processor dependent. Therefore, to enhance
portability a program should not use literal kind values. There are typically
several ways to obtain kind values for a type in a portable manner, so most of
the time there is no need for the programmer to know what value a kind type
parameter has.
A processor might provide several representation methods of character type in
order to support different character sets; these might or might not have
different storage sizes. Character sets that are likely to be available
include ISO 646 and ISO 10646 (UCS-4); these can be selected using the
intrinsic function SELECTED_CHAR_KIND. A list of supported character kinds is
available via the named constant CHARACTER_KINDS in the intrinsic module
ISO_FORTRAN_ENV.
The approximation methods for the complex type are the same as those for the
real type.
A representation method for the integer type is characterised by its decimal
range of values (this is likely to affect the storage size required by that
kind of integer). The integer type is required to have a representation method
with a decimal range greater than 18, and therefore many processors will
support more than one representation. The intrinsic function SELECTED_INT_KIND
returns a kind type parameter value based on the decimal range of values. A
list of supported integer kinds is available via the named constant
INTEGER_KINDS in the intrinsic module ISO_FORTRAN_ENV. This intrinsic module
also contains named constants for commonly required integer representation
methods: INT8, INT16, INT32, and INT64.
The logical type has only two values; each representation method has the same
set of valid values. However, different representation methods are likely to
have different storage sizes. There is no intrinsic function for selecting a
logical kind, but a list of supported kinds is available via the named constant
LOGICAL_KINDS in the intrinsic module ISO_FORTRAN_ENV.
An approximation method of the real type is characterised by its decimal
precision and decimal exponent range. The real type is required to have at
least two approximation methods. The intrinsic function SELECTED_REAL_KIND
returns the kind type parameter value for an approximation with the desired
precision and range. A list of supported real kinds is available via the named
constant REAL_KINDS in the intrinsic module ISO_FORTRAN_ENV. This intrinsic
module also contains named constants for commonly required approximation
methods: REAL32, REAL64, and REAL128.
It is recommended that when a program requires a particular approximation
method or representation method, that the kind value be selected by a module
which is then used by the whole program.
For example
MODULE working_precision
INTEGER, PARAMETER :: wp = SELECTED_REAL_KIND(15)
END MODULE
...
USE working_precision
REAL(wp) :: pisq = 3.1415926535897932384626433832795028841_wp**2
This is particularly useful if the precision of a program needs to be changed
during or after development.
The following example displays information about specific kinds of a type.
PROGRAM display_kind_info
USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY: int32, real64
PRINT 1, 'int32 information'
1 FORMAT(/,A)
PRINT 2, 'bit size ', bit_size( 0_int32)
2 FORMAT(1X,A13,I0)
PRINT 2, 'digits ', digits( 0_int32)
PRINT 2, 'huge ', huge( 0_int32)
PRINT 2, 'radix ', radix( 0_int32)
PRINT 2, 'storage size ', storage_size( 0_int32)
PRINT 1, 'real64 information'
PRINT 2, 'digits ', digits( 0.0_real64)
PRINT 3, 'epsilon ', epsilon( 0.0_real64)
3 FORMAT(1X,A13,ES24.16)
PRINT 3, 'huge ', huge( 0.0_real64)
PRINT 2, 'max exponent ', maxexponent( 0.0_real64)
PRINT 2, 'min exponent ', minexponent( 0.0_real64)
PRINT 2, 'precision ', precision( 0.0_real32)
PRINT 2, 'radix ', radix( 0.0_real64)
PRINT 2, 'storage size ', storage_size( 0.0_real64)
PRINT 3, 'tiny ', tiny( 0.0_real64)
END PROGRAM
Note that kind type parameters are also available for user-defined derived
types; the meaning of such kind type parameters is user-defined.
===END===