Search code examples
fortran

Is Fortran's DBLE intrinsic function obsolete?


In the Fortran standard, dble is an intrinsic function in the same way as real. The recommended way of working with double precision numbers is to use iso_fortran_env. Thus, we have two ways of converting to double

program demo
 use iso_fortran_env, only : REAL64, INT32
 integer(INT32) :: i
 real(REAL64)   :: x, y
 i = 5
 x = dble(i)
 y = real(i, REAL64)
end program demo

But is there a difference between dble(...) and real(...,REAL64)? Are there usage cases where one form should be preferred over the other?

Isn't it that the very existence of iso_fortran_env makes dble obsolete? Or conversely, if every compiler is supposed to know what double type is why do we need iso_fortran_env (it might be very useful for other purposes though)?


Solution

  • dble is obsolete in some sense,1 but this obsolescence is entirely unrelated to the existence of real64 from iso_fortran_env.

    The following are equivalent:

    double precision x
    x = dble(1)
    end
    

    and

    real(kind(0d0)) y
    y = real(1, kind(0d0))
    end
    

    Indeed, the result of dble in the first is defined precisely as that of real in the second.

    The following are not equivalent:

    double precision x
    x = dble(1)
    end
    

    and

    use, intrinsic :: iso_fortran_env, only : real64
    real(real64) y
    y = real(1, real64)
    end
    

    x and y may have the same kind, but they may also be different: real64 is not guaranteed to be a valid kind number (a processor may not have a 64-bit storage real); even if double precision is a 64-bit real, that doesn't mean real64 is that kind (there could be two more more 64-bit reals).

    This is all to say, whatever one thinks about double precision as a type declaration, it's entirely wrong to think of replacing it with real(real64) instead of real(rk) where rk is the equivalent kind number for the processor's double precision.

    "Double precision" in Fortran doesn't mean the same thing as "double precision" in IEEE floating point, but they may happen to match up. real(real64) means neither Fortran's "double precision" nor IEEE's "double precision" but may match one or the other or both.


    Some historical context, to place the comment discussion: back in Fortran 77 (and before) the "double precision" was a completely different type from the "real". In Fortran 77 real(y) returns a real and dble(y) returns a double precision.

    Only in Fortran 90 were the two unified to being kinds of the same type. We had dble() and double precision back then because of these differing types. Even though now we can use real(kind=kind(0d0)) x and real(y, kind=kind(0d0) we retain the history of the other ways, in a manner which is backward compatible. No deletion of the "obsolete" forms, which will break decades' code, is going to happen.


    1 It is certainly not defined as "obsolete" by the Fortran standard.