I was reading about Fortran’s intrinsic function
REAL recently and discovered that it behaved inconsistently, so I fixed it by overloading the function in a
module that I generally
REAL to extract the real part of a complex number. The
KIND of the return value is equal to that of it’s argument, but only if the argument is
COMPLEX. If the argument itself is of type
REAL, then it returns a value using the compiler’s default
REAL KIND. For me, since I program in double precision, this can cause me to accidentally lose precision, if I’m not careful.
I see three ways to fix this:
- Always include the
REAL, for example
REAL(foo,8). I’m likely to forget, and it clutters my code without adding information to the reader.
- Change the compiler default
KIND. In gfortran, I just need a command-line argument:
gfortran -fdefault-real-8. However, this option can change from compiler to compiler.
- Overload the intrinsic function to return a
REALvalue with the same
KINDas the argument.
So, I went with the last option. To get this to work, I put the function in my
module prec_def, which is where I set the precision for the entire code. I used an
interface for the overloading, so that I only overrode the intrinsic for the argument names and types that I specify.
Here’s the result:
use iso_fortran_env, only : REAL64 !to get the KIND parameter for 64-bit precision
integer, parameter :: long=REAL64
module procedure real_real
real(Long) function real_real(num)
real(Long), intent(in) :: num
!call the intrinsic function, specifying KIND
real_real = real(num,Long)
end function real_real
end module prec_def
Let me know what you think!