On Mon, 8 Mar 2004 11:41:12 -0800, <[log in to unmask]> wrote:
> It's trivial to avoid ambiguities. The standard requires that default
> real and double precision are different kinds. So I write a real version
> and a double precision version of each library procedure, and glue them
> together to make a generic. I use kind(0.0e0) and kind(0.0d0) to get
> the kind numbers, and then frequently use "include" so as not to need to
> write the body twice.
>
> I agree that trying to do generic resolution based on selected_real_kind
> is an invitation to portability problems. Therefore I **never** use
> selected_real_kind to get the kind numbers for generic resolution,
> because selected_real_kind(6) and selected_real_kind(12) might be the
> same kind. That's the source of the ambiguity that may be the one Alvaro
> is trying to avoid.
I know what you mean above, but let me offer a use for
selected_real_kind. I was looking through the list archive to see
what has been said about real precisions before, and found the
expression "SELECTED_REAL_KIND(PRECISION(0.0)+1)".
Now I never thought of that one. This expression seems to have
interesting uses for simple cases. Here's an example module coded
for just one kind.
MODULE AUTOGEN_1
INTEGER, PARAMETER :: R_ = SELECTED_REAL_KIND(1)
INTERFACE SUB
MODULE PROCEDURE SUB
END INTERFACE SUB
CONTAINS
SUBROUTINE SUB(PI)
REAL(R_), INTENT(OUT) :: PI
PI = 4*ATAN(1.0_R_)
END SUBROUTINE SUB
END MODULE AUTOGEN_1
This module offers a subroutine SUB, which is generic, but only
given for one kind (with the least precision, perhaps the
default real). Copy and paste the same module to the end of
this file, then change the first two lines of the new module to
MODULE AUTOGEN_2
USE AUTOGEN_1, R_1 => R_
INTEGER, PARAMETER :: R_ = SELECTED_REAL_KIND(PRECISION(0.0_R_1)+1)
and the last line to
END MODULE AUTOGEN_2
and now the generic name can resolve to the double precision kind
(without changing any other line, not even the procedure names).
Of course, the caller needs to USE AUTOGEN_2 instead of AUTOGEN_1.
Copy and paste AUTOGEN_2, changing the first three lines and the
last line to
MODULE AUTOGEN_3
USE AUTOGEN_2, R_2 => R_
INTEGER, PARAMETER :: R_ = SELECTED_REAL_KIND(PRECISION(0.0_R_2)+1)
END MODULE AUTOGEN_3
(just increment the numbers by one), and you get the next
precision. This can be repeated mechanically for as many
different kinds as the processor supports. So for the
simple case of no mixed precision arithmetic,
SELECTED_REAL_KIND seems to offer an "automatic" way to
convert a single-kind source into generic-for-all-reals.
Just to test the concept I made a 51-line program to
do this conversion (crudely). It's placed at
http://mns2.c.u-tokyo.ac.jp/arasaki/autogen/
Might be useful for something?
--
Yasuki Arasaki
[log in to unmask]
|