J3/12-164 To: J3 From: Dan Nagle Subject: Update Kinds Discussion in Annex Date: 2012 June 23 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: {Editor, improve the kind discussion in the explanatory annex} [467:5-27] Delete the existing C.1.1 [467:28-] Add C.1.1 Selection of Representations of Intrinsic Types (4.4.2.3) All the intrinsic types (logical, integer, character, real and complex) allow several representations to be used by a processor. Real and complex are required to have at least two, while integer must have one with a decimal range greater than 18, and therefore many processors will support more than one representation. Kind type values are processor-dependent. Therefore, for maximum portability a program should never use literal kind values. There are several ways to obtain kind values for any type, and do so in a completely portable way. Indeed, there is no need to know what value a kind type parameter is. Type logical has only two values so different representations have the same set of values and may be used interchangeably. Processors may choose to support different representations of type logical to provide entities of different storage sizes. Processors may support several representations of type character to support several character sets. These representations will likely have different storage sizes. For most processors, these character sets are taken from the ISO 10646 family of character sets, although there is no reason not to support other character sets. The most important factors involving integers is the range of values an integer may support and the storage size required to do so. The representation of type integer required to have a range greater than 18 may be implemented as a 64-bit integer. A processor may well support an integer representation smaller than 64 bits, such as a 32-bit integer. There are three ways to obtain a kind type value for type integer (without using a literal value). These are the selected_int_kind intrinsic, the integer_kinds array defined in the iso_fortran_env intrinsic module, and the named constants int32 and int64 defined in the iso_fortran_env intrinsic module. An example follows. program diagnose_integers use, intrinsic :: iso_fortran_env, only: int32, int64 write( *, '( / a)') 'for int32' write( *, '( a13, i0)') 'bit size ', bit_size( 0_int32) write( *, '( a13, i0)') 'digits ', digits( 0_int32) write( *, '( a13, i0)') 'huge ', huge( 0_int32) write( *, '( a13, i0)') 'radix ', radix( 0_int32) write( *, '( a13, i0)') 'storage size ', storage_size( 0_int32) write( *, '( / a)') 'for int64' write( *, '( a13, i0)') 'bit size ', bit_size( 0_int64) write( *, '( a13, i0)') 'digits ', digits( 0_int64) write( *, '( a13, i0)') 'huge ', huge( 0_int64) write( *, '( a13, i0)') 'radix ', radix( 0_int64) write( *, '( a13, i0)') 'storage size ', storage_size( 0_int64) end program diagnose_integers The most important factors involving reals is the range of values a real may support, the precision it supports, and the storage size required to do so. A processor is required to support two representations of type real one of which will require twice the storage of the other. Of course, a processor is allowed to support further representations of type real as well. One representation may be implemented as a 64-bit integer. A processor may well support a real representation smaller than 64 bits, such as a 32-bit real. There are three ways to obtain a kind type value for type real (without using a literal value). These are the selected_real_kind intrinsic, the real_kinds array defined in the iso_fortran_env intrinsic module, and the named constants real32 and real64 defined in the iso_fortran_env intrinsic module. An example follows. program diagnose_reals use, intrinsic :: iso_fortran_env, only: real32, real64 write( *, '( / a)') 'for real32' write( *, '( a13, i0)') 'digits ', digits( 0.0_real32) write( *, '( a13, es24.16)') 'epsilon ', epsilon( 0.0_real32) write( *, '( a13, es24.16)') 'huge ', huge( 0.0_real32) write( *, '( a13, i0)') 'max exponent ', maxexponent( 0.0_real32) write( *, '( a13, i0)') 'min exponent ', minexponent( 0.0_real32) write( *, '( a13, i0)') 'precision ', precision( 0.0_real32) write( *, '( a13, i0)') 'radix ', radix( 0.0_real32) write( *, '( a13, i0)') 'storage size ', storage_size( 0.0_real32) write( *, '( / a)') 'for real64' write( *, '( a13, i0)') 'digits ', digits( 0.0_real64) write( *, '( a13, es24.16)') 'epsilon ', epsilon( 0.0_real64) write( *, '( a13, es24.16') 'huge ', huge( 0.0_real64) write( *, '( a13, i0)') 'max exponent ', maxexponent( 0.0_real64) write( *, '( a13, i0)') 'min exponent ', minexponent( 0.0_real64) write( *, '( a13, i0)') 'precision ', precision( 0.0_real32) write( *, '( a13, i0)') 'radix ', radix( 0.0_real64) write( *, '( a13, i0)') 'storage size ', storage_size( 0.0_real64) end program diagnose_reals Note that there is no need to know that value of the type kind value in order to fully diagnose the representation of the kinds supported. If it is imagined that a kind value might be changed after a program has been substantially developed, use of a rename clause on the use statement of the iso_fortran_env intrinsic module isolates the changes to a single line. use, intrinsic :: iso_fortran_env, only: wrk => real64 If a change is desired, the 'real64' is all that must be changed if wrk is used throughout the scope to supply the kind value.