From: ralf.schaa on 6 Jan 2010 19:39 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 6 Jan 2010 19:46 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 6 Jan 2010 20:37 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 7 Jan 2010 03:32 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 7 Jan 2010 08:45
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 |