From: ralf.schaa on
probably a faq, but here goes...
i would like to write lengthy formulae without the *.0d0 (or other
specified kind types) and use, where possible, the integer, for
example:

real( double ) :: t, phi
t = 5+tan(phi)

I think this should not result in a precision loss, is it?

What about division?

t = 5+tan(phi) / 3 ?

Cheers
-Ralf
From: Tim Prince on
ralf.schaa wrote:
> probably a faq, but here goes...
> i would like to write lengthy formulae without the *.0d0 (or other
> specified kind types) and use, where possible, the integer, for
> example:
>
> real( double ) :: t, phi
> t = 5+tan(phi)
>
> I think this should not result in a precision loss, is it?
>
> What about division?
>
> t = 5+tan(phi) / 3 ?
>

Those integers are promoted automatically to real(double) before adding,
an exact operation. The compiler would choose whether it is at compile
or run time. Certain compilers may promote /3 to *1/real(3,double) at
compile time (at full optimization) but would do the same with /3_double.
From: glen herrmannsfeldt on
ralf.schaa <ralf.schaa(a)gmail.com> wrote:
> probably a faq, but here goes...
> i would like to write lengthy formulae without the *.0d0 (or other
> specified kind types) and use, where possible, the integer, for
> example:

> real( double ) :: t, phi
> t = 5+tan(phi)

> I think this should not result in a precision loss, is it?

For add, subtract, multiply and divide if the other operand is an
appropriate REAL kind then an integer will be converted to the
same kind before the operation. There should be no loss.
In days past there were suggestions that some might do the conversion
at run time, but that should not be a problem for any current compiler.

> What about division?

If both arguments are integers then integer division will be done.
Otherwise it should be fine.

> t = 5+tan(phi) / 3 ?

For powers, you normally want an integer for the power if it
is actually integer. That is, use x**3 instead of x**3.0D0.

Also, not that unlike some other languages you still can't
do tan(3) and have an appropriate conversion done for you.

-- glen
From: Arjen Markus on
On 7 jan, 01:39, "ralf.schaa" <ralf.sc...(a)gmail.com> wrote:
> probably a faq, but here goes...
> i would like to write lengthy formulae without the *.0d0 (or other
> specified kind types) and use, where possible, the integer, for
> example:
>
> real( double ) :: t, phi
> t = 5+tan(phi)
>
> I think this should not result in a precision loss, is it?
>
> What about division?
>
> t = 5+tan(phi) / 3 ?
>
> Cheers
> -Ralf

However, a formula like:

t = 0.1 + tan(phi)

will result in a loss of precision, if t and phi are double precision.
0.1 is still a single-precision literal and that gets promoted to
double precision with the addition.

So in that case:

t = 0.d0 + tan(phi)

is the correct way to proceed.

Probably better to avoid literals and use parameters instead. Then
the precision can be controlled in one place.

Regards,

Arjen

From: glen herrmannsfeldt on
Arjen Markus <arjen.markus895(a)gmail.com> wrote:
(snip)

> However, a formula like:

> t = 0.1 + tan(phi)

> will result in a loss of precision, if t and phi are double
> precision. 0.1 is still a single-precision literal and that
> gets promoted to double precision with the addition.

http://en.wikipedia.org/wiki/Accuracy_and_precision

I would say that the pricision is fine, but the accuracy is not.
The multiplication will be done in double precision with a value
that is not as close to 0.1d0 as it should be. (Assuming binary
hardware.) Small changes in tan(phi) will result in appropriate
small changes in t (precision), but likely the wrong value for t.

> So in that case:

> t = 0.d0 + tan(phi)

> is the correct way to proceed.

> Probably better to avoid literals and use parameters instead. Then
> the precision can be controlled in one place.

For the example given, the accuracy is even worse than for 0.1
due to a typographic error. 0.d0 is not better than 0.1e0 in
this case.

-- glen