Re: whole number constants
- From: nospam@xxxxxxxxxxxxx (Richard Maine)
- Date: Mon, 21 Jul 2008 15:00:02 -0700
<dancerchris@xxxxxxxxxxxxx> wrote:
I still would like to understand what the best practice is. writing
global constants for whole numbers like 1 seems redundant.
It pretty much is. You will have no precision loss from expressing whole
numbers of "reasonable" magnitude in any actual compiler. It doesn't
matter whether you express it as a real or an integer, and it doesn't
matter what kind.
There are two cases where it does matter.
1. When you start doing operations. There is a big difference between
1/3.0 and 1/3.0d0. There is an even bigger difference between these and
1/3.
2. In procedure arguments, you must have the type and kind correct.
That's pretty much all there is to say about that. There is no single
type and kind that is always the best one. You just have to use the
correct one for the particular procedure in question.
I don't have a magic "best practice" other than to pay attention to
data type. Don't count on some single "best practice" to be the right
thing for all cases. Instead, make it a habit to consciously think about
the type and kind of your data. That being said, I personally do tend to
have a parameter named one because it is often convenient.
On your specific question
real(dp), parameter :: one = 1.0_dp
real(dp), parameter :: onend = 1_dp
real(dp), parameter :: onenk = 1.0
real(dp), parameter :: onei = 1
All of these are equivalent, except for the 1_dp. As noted previously,
that one is basically nonsense. The 1.0_dp form is technically the "most
correct". I also think it is the clearest; the other two valid ones seem
subject to human misreading, though the compiler will get them right. It
will implicitly convert them to the type and kind of the parameter. In
the case of whole numbers, this conversion will be exact. Note that it
is *NOT* exact in other cases. Something like
real(dp), parameter :: one_third = 1./3.
will be accurate only to single precision, and if you make the
right-hand-side 1/3, the resulting value will be just 0.
! which should I use ?
10 error = one-xnew/x
20 error = onend-xnew/x
30 error = onenk-xnew/x
40 error = onei-xnew/x
! or the more ledgable ?
50 error = 1-xnew/x
! or the slightly less ledgable ?
60 error = 1_dp-xnew/x
Other than the nonsense case of 1_dp, which was mentioned before, all
these are equivalent. You need to learn the basic rule of implicit
conversion for the intrinsic numeric operators. When a numeric operator
has operands of two different types or kinds, the operand of "lower
precision" is converted to the higher precision before performing the
operation. For the purposes of this description, integers count as
having "lower precision" than reals.
Furthermore, all your variously named parameters have the same type and
kind anyway. Once you know the type, kind, and value of the parameter,
the rest is irrelevant. It doesn't matter how that value got defined.
The compiler doesn't "remember" that your onei got defined by converting
an integer value.
--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
.
- References:
- whole number constants
- From: dancerchris
- Re: whole number constants
- From: Craig Powers
- Re: whole number constants
- From: dancerchris
- whole number constants
- Prev by Date: Re: whole number constants
- Next by Date: Re: whole number constants
- Previous by thread: Re: whole number constants
- Next by thread: Re: whole number constants
- Index(es):
Relevant Pages
|