I understand that .d0
denotes double precision
however I wonder how it goes together with user defined precision. I use
module precision
implicit none
integer, parameter :: DP = selected_real_kind(r=250,p=13)
end module precision
and declare floats as
real(KIND=DP) :: var1
Whenever I need to assign a value to such a float somewhere in the programme I do
var1 = 1_DP
Now the problem I have is that it does not work if I read the value from a namelist. The compiler insists on
&namelistName
var1 = 1.d0
!var1 = 1_DP ! this does not work
&end
Two questions follow:
1.d0
to a variable declared as real(KIND=DP)
?1_DP
in namelists? If it matters of course. Fortran 77 has only one loop construct, called the do-loop. The do-loop corresponds to what is known as a for-loop in other languages. Other loop constructs have to be built using the if and goto statements.
The "real*4" statement specifies the variable names to be single precision 4-byte real numbers which has 7 digits of accuracy and a magnitude range of 10 from -38 to +38. The "real" statement is the same as "real*4" statement in nearly all 32-bit computers.
In addition to addition +, subtraction -, multiplication * and division /, Fortran has an exponential operator **. Thus, raising X to the Y-th power is written as X**Y. For example, the square of 5 is 5**2, and the square root of 5 is 5**0.5. The exponential operator has the highest priority.
The INTEGER statement specifies the type to be integer for a symbolic constant, variable, array, function, or dummy function. Optionally, it specifies array dimensions and size and initializes with values.
Double precision constant 1.23d45 Fortran 90 introduced parameterized real types using kinds. The kind of a real type is an integer named constant or literal constant: real (kind=real_kind) :: x
x here is a real of default kind and y is a real of kind with greater decimal precision than x. In Fortran 2008, the decimal precision of y is at least 10 and its decimal exponent range at least 37. real, parameter :: single = 1.12345678901234567890 double precision, parameter :: double = 1.12345678901234567890d0 print *, single print *, double
In Fortran 2008, the decimal precision of y is at least 10 and its decimal exponent range at least 37. real, parameter :: single = 1.12345678901234567890 double precision, parameter :: double = 1.12345678901234567890d0 print *, single print *, double
Notice the d0 in the double precision constant. A real literal containing d instead of e for denoting the exponent is used to indicate double precision. ! Default single precision constant 1.23e45 ! Double precision constant 1.23d45 Fortran 90 introduced parameterized real types using kinds.
The whole concept of kinds makes sense only in the source code, there is no way making it work for input data, because at runtime the system knows nothing about them.
In the source code
1.d0
is a double precision real,
1._dp
is a real with kind dp
,
1_dp
is an integer (no decimal there) with kind dp
.
In the input data you don't need to specify the precision at all, you just need a number. The runtime system then converts the string with a number to the right type of variable you are trying to read.
You can use 1.e0
, 1.d0
, as an extension maybe even 1.q0
, just to be flexible, but it doesn't change the meaning. In the input file it is just a string representing a number.
What happens, if you in the source code assign
real(dp) :: x = 1.d0
?
It is just simply assigned if the dp
kind is the same kind as the double precision. Otherwise it is converted. If the real constant value is a small integer, the conversion is simple and no precision is lost as they are represented exactly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With