    module inf_and_nan
!  INF_AND_NAN - provide an interface for elemental procedures to check
!  for arguments that are positive infinity or NaN.
!  These routines are compiler-specific.  In particular, they depend
!  on optimizers not to eliminate the checks that they perform.
!  NaNs compare unequal to everything, including themselves; so if
!  none of .eq., .gt., or .lt. is true for two real arguments, then
!  one or both must be NaN.  Similarly, Inf is greater than any floating-point
!  quantity.
!
    use precision
    private::rcompare,dcompare
!
    interface isnan
       module procedure r_isnan
       module procedure d_isnan
    end interface 
!
    interface isinf
       module procedure r_isinf
       module procedure d_isinf
    end interface 
    contains
! ------------------------------------------------
    elemental logical function r_isnan(x)
!  R_ISNAN - is the real number X a NaN?
!
    real(R),intent(in)::x
    real(R)::y
    y=x
    r_isnan=.not.rcompare(x,y)
    return
    end function r_isnan
! ------------------------------------------------
    elemental logical function d_isnan(x)
!  D_ISNAN - is the double-precision number X a NaN?
!
    real(D),intent(in)::x
    real(D)::y
    y=x
    d_isnan=.not.dcompare(x,y)
    return
    end function d_isnan
! ------------------------------------------------
    elemental logical function r_isinf(x)
!  R_ISINF - is the real number X equal to positive infinity?
!
    real(R),intent(in)::x
    r_isinf=x.gt.huge(x)
    return
    end function r_isinf
! ------------------------------------------------
    elemental logical function d_isinf(x)
!  D_ISINF - is the double precision number X equal to positive infinity?
!
    real(D),intent(in)::x
    d_isinf=x.gt.huge(x)
    return
    end function d_isinf
! ------------------------------------------------
    elemental logical function rcompare(x,y)
!  DCOMPARE - return true if the real numbers X and Y are not NaNs.
!
    real(R),intent(in)::x,y
    rcompare=x.lt.y.or.x.gt.y.or.x.eq.y
    return
    end function rcompare
! ------------------------------------------------
    elemental logical function dcompare(x,y)
!  DCOMPARE - return true if the double-precision numbers X and Y are not NaNs.
!
    real(D),intent(in)::x,y
    dcompare=x.lt.y.or.x.gt.y.or.x.eq.y
    return
    end function dcompare
! ------------------------------------------------
    end module inf_and_nan
