I am using Fortran90. I would like to declare 'pi' as a double precision parameter.
How can I express 'pi' value in double precision,and how many decimal points should I consider in this case?
Can anybody help me in this regard?
I'm sure there are other ways of defining pi, but I always use atan, which is an intrinsic function that has been available in all Fortrans.
The use of atan in a parameter statement is a recent version of fortran.
This should give some idea of the precision available.
real(8), parameter :: PI_8 = 4 * atan (1.0_8)
real(16), parameter :: PI_16 = 4 * atan (1.0_16)
write (*,*) pi_8
write (*,*) pi_16
pi_8=acos(-1.0_8) works as well and you are sure that cos(pi_8)=-1.
I made a test program to see how good "4 * acos(1.0_8)" really is and was surprised it gave the same answer as the most accurate value I could find.
real(8), parameter :: piCalculated = 4 * atan(1.0_8)
real(8), parameter :: piAccurate = 3.1415926535897932_8
print *, piCalculated, piAccurate, piCalculated - piAccurate
print *, cos(piCalculated) + 1.0_8, cos(piAccurate) + 1.0_8
3.14159265358979 3.14159265358979 0.000000000000000E+000
The answer should be that accurate, as your piAccurate is truncated to real*8 storage. If it wasn't we'd be asking more questions.
As I don't use real*16 very often, I wonder and am amazed at the accuracy of these calculations, as I can never provide input data of sufficient accuracy.
Thanks, Andrew & John once again. However, I have declared all variables as double precision, so I want to declare PI as a double precision parameter. Can I declare DOUBLE PRECISION, PARAMETER::pi=4.0D0*DATAN(1.0D) instead of REAL(8), PARAMETER :: pi = 4 * ATAN(1.0_8)?
Sorry, for making a mistake. I wanted to write DOUBLE PRECISION, PARAMETER::pi=4.0D0*DATAN(1.0D0), where D means double precision.
I prefer "4 * ATAN (1.0d0)" as
ATAN as I prefer to use the generic name rather than DATAN. (DATAN indicates the code is probably Fortran 77)
4.0d0 is not required as ATAN implies a real*8 calculation and 4 converts to 4.0d0 with no loss of accuracy. 4 is easier to read.
Although it is non portable, for me, 1.0_8 does document the precision more clearly than 1.0d0. (1.0e0 is very different but has a similar interpretation outside Fortran)