On Thu, 2017-04-06 at 11:28 -0400, Vipul Parekh wrote:
> Van,
>
>
> Is the use of KIND(1.0e0) and KIND(1.0d0) just as 'portable' as
> SELECTED_REAL_KIND? My reading and experience suggest otherwise, but
> I may be wrong. Can you please share your views?
I have not encountered a case where this standard-conforming usage does
not work.
> More specifically, consider the following from the scenario you
> presented involving some generics: the blog in question (the one I
> mentioned in the first note) effectively considered 2 of these options
> and emphatically states SELECTED_REAL_KIND is what coders should use.
> What do you say and why? Thanks,
It depends on what you're doing. If you have an application wherein you
know the data are only good for six digits, you ought to use
SELECTED_REAL_KIND(6). If you create a generic with specifics with this
and SELECTED_REAL_KIND(12) you will not be able to compile it if REAL64
is the same as KIND(1.0e0). To do this, you need new types, not new
names for two REALs that have different kind type parameters on some
systems and the same kind type parameters on other systems.
If you're developing "library" code that will be used in places where
the underlying physical phenomenon is irrelevant, you should create
default real and double precision versions, glued together with a
generic interface.
> Option 1: begin --
>
> ..
>
> function F_s( X )
> use ISO_FORTRAN_ENV, only : RK => REAL32
> ..
> end function F_s
> ..
>
> function F_d( X )
> use ISO_FORTRAN_ENV, only : RK => REAL64
> ..
> end function F_s
> -- end Option 1 --
>
>
> Option 2: begin --
>
> ..
>
> function F_s( X )
> integer, parameter :: RK = SELECTED_REAL_KIND( p=N_s, r=M_s ) !
> N_s and M_s are arbitrary values for single precision
> !
> e.g., 6, 37
> ..
> end function F_s
> ..
>
> function F_d( X )
> integer, parameter :: RK = SELECTED_REAL_KIND( p=N_d, r= M_d ) !
> N_s and M_d are arbitrary values for single precision
> !
> e.g., 15, 307
> ..
>
> end function F_s
> -- end Option 2 --
>
>
> Option 3: begin --
>
> ..
>
> function F_s( X )
> integer, parameter :: RK = KIND(1.0e0)
> ..
> end function F_s
> ..
>
> function F_d( X )
> integer, parameter :: RK = KIND(1.0d0)
> ..
>
> end function F_s
> -- end Option 3 --
>
>
> So do you really prefer Option 3 from above? If so,
> 1) Why?
> 2) What would you do if you needed extended precision, say the
> equivalent of binary128 from IEEE 754 standard?
>
>
> Thanks,
> Vipul
>
>
>
>
> On Thu, Apr 6, 2017 at 2:43 AM, Van Snyder <[log in to unmask]>
> wrote:
> On Wed, 2017-04-05 at 11:29 +0200, Phillip Helbig wrote:
> > I understand the motivation for KIND. However, many people
> use
> > SELECTED_REAL_KIND with 1.0D0 or whatever to find the
> > "double-precision KIND". Why not just write DOUBLE
> PRECISION if that
> > is what you mean?
>
> I use INCLUDE as a poor-man's substitute for generic
> programming.
>
> I use a kind type parameter to specialize a function to
> default real or
> double precision, to produce a generic interface, like this:
>
> interface F
> module procedure F_d, F_s
> end interface
> ...
> function F_d ( X )
> integer, parameter :: RK = kind(1.0d0)
> include "F_body.f9h"
> end function F_d
>
> function F_s ( X )
> integer, parameter :: RK = kind(1.0e0)
> include "F_body.f9h"
> end function F_s
>
> with F_body.f9h containing
>
> ! function F_* ( X )
> real(rk) :: F
> real(rk), intent(in) :: F
> ...
>
> This doesn't work if I use DOUBLE PRECISION.
>
>
|