Search code examples
fortrangfortranfortran95

Maximum value of 64 bit floating point number for overflow detection


I have a seemingly simple problem: I want to detect whether a floating point addition in Fortran will overflow by doing something like the following:

real*8 :: a, b, c

a = ! some value
b = ! some value

if (b > DOUBLE_MAX - a) then
  ! handle overflow
else
  c = a + b

The problem is that I don't know what DOUBLE_MAX should be. I'm aware of how floating point numbers are represented according to IEEE 754 but the largest value representable by a double precision floating point number seems to be too large for a variable of type real*8 (i.e. if I try to assign 1.7976931348623157e+308 to such a variable gfortran complains). C and C++ have predefined constants/generic functions for this purpose but I couldn't find a Fortran equivalent.

Note: I'm aware that real*8 is not really part of the standard but there seems to be no other way to reliably specify that a floating point number should use the double precision format.


Solution

  • Something like this?

    real(REAL64) function func( a, b )
      use, intrinsic :: iso_fortran_env, only: REAL64, INT64
      use, intrinsic :: ieee_arithmetic, only: ieee_value, ieee_set_flag, IEEE_OVERFLOW, IEEE_QUIET_NAN
      implicit none
      real(REAL64), intent(in) :: a, b
      real(REAL64), parameter  :: MAX64 = huge(0.0_REAL64)
    
      if ( b > MAX64-a ) then
        ! Set IEEE_OVERFLOW flag and return NaN
        call ieee_set_flag(IEEE_OVERFLOW,.true.)
        func = ieee_value(func,IEEE_QUIET_NAN)
      else
        func = a + b
      end if
    
      return
    end function func
    

    All I could find for intrinsic ieee_exceptions module is:
    https://github.com/gcc-mirror/gcc/blob/master/libgfortran/ieee/ieee_exceptions.F90

    For setting NaN value see post.