!! Provide named kind parameters for use in declarations of !! real and integer variables with specific byte sizes !|author: Giovanni Ravazzani ! license: GPL ! !### History ! ! current version: 1.0 - 4th July 2008 ! ! | version | date | comment | ! |----------|-------------|----------| ! | 1.0 | 4/Jul/2008 | Original code | ! ! !### License ! license: GNU GPL ! ! This file is part of ! ! MOSAICO -- MOdular library for raSter bAsed hydrologIcal appliCatiOn. ! ! Copyright (C) 2011 Giovanni Ravazzani ! !### Code Description ! Language: Fortran 90. ! ! Software Standards: "European Standards for Writing and ! Documenting Exchangeable Fortran 90 Code". ! !### Module Description ! ! Motivation: ! ! Portability refers to the ease with which source code can be moved ! from machine to machine. A portable program requires little or no ! change to the source code when compiled and run on a different machine. ! Portability of numerical code is important for several reasons. ! Fortran 90 introduces several new mechanisms to aid in porting numerical ! code to other machines. The most difficult problem in porting numerical ! programs is in the portable selection of precision. Selecting the precision ! of a computation in a portable way was impossible with Fortran 77. ! However, with the introduction of kind values as well as intrinsic ! environmental inquiry functions for selecting and inquiring about ! precision, Fortran 90 programs should be much easier to port to other machines. ! Kind values are integer constants that can be used to further specify ! the characteristics of an intrinsic type, such as integer or real. ! For example, real( 2 ) selects a real type with kind value 2. ! Unfortunately, kind values are processor-dependent and are therefore ! not standardized. However, there are several portable ways to ! select kind values based on the precision desired. Two such functions ! are selected_int_kind and selected_real_kind ! ! Description: ! ! Provide named kind parameters for use in declarations of real and integer ! variables with specific byte sizes (i.e. one, two, four, and eight byte ! integers; four and eight byte reals). The parameters can then be used ! in (KIND = XX) modifiers in declarations. ! A single function (SizesOK()) is provided to ensure that the selected ! kind parameters are correct. ! ! References and Credits: ! ! Adapted from netCDF library http://www.unidata.ucar.edu/software/netcdf/ ! Written by Robert Pincus ! ! Design Notes: ! ! Fortran 90 doesn't allow one to check the number of bytes in a real variable; ! we check only that four byte and eight byte reals have different kind parameters. ! MODULE DataTypeSizes IMPLICIT NONE ! Global (i.e. public) Declarations: !| 32 bits integer type !equivalent to FourByteInt type in netCDF library INTEGER, PUBLIC, PARAMETER :: short = SELECTED_INT_KIND(9) !| 64 bits integer type !equivalent to EightByteInt type in netCDF library INTEGER, PUBLIC, PARAMETER :: long = SELECTED_INT_KIND(18) !| 32 bits real type ! floating point numbers with numerical precision at least 6 digits ! and one decimal exponent range between -37 and +37 ! equivalent to FourByteReal type in netCDF library INTEGER, PUBLIC, PARAMETER :: float = SELECTED_REAL_KIND(P = 6, R = 37) !| 64 bits real type ! floating point numbers with numerical precision at least 13 digits ! and one decimal exponent range between -307 and +307 ! equivalent to EightByteReal type in netCDF library (double precision) INTEGER, PUBLIC, PARAMETER :: double = SELECTED_REAL_KIND(P = 13, R = 307) !======= CONTAINS !======= ! Define procedures contained in this module. !============================================================================== !| Description: ! Users may call this function once to ensure that the kind parameters ! the module defines are available with the current compiler. ! We can't ensure that the two REAL kinds are actually four and ! eight bytes long, but we can ensure that they are distinct. ! Early Fortran 90 compilers would sometimes report incorrect results for ! the bit_size intrinsic, but I haven't seen this in a long time. LOGICAL FUNCTION SizesOK & ! () IMPLICIT NONE ! Local scalars: INTEGER (KIND = short) :: short_int INTEGER (KIND = long) :: long_int REAL (KIND = float) :: float_real REAL (KIND = double) :: double_real !------------end of declaration------------------------------------------------ IF (BIT_SIZE( short_int) == 32 .AND. BIT_SIZE( long_int) == 64 .AND. & float > 0 .AND. double > 0 .AND. float /= double ) THEN SizesOK = .TRUE. ELSE SizesOK = .FALSE. END IF END FUNCTION SizesOK END MODULE DataTypeSizes