Is there a way to know if a variable is NaN, +infinity, -infinity?

Intel Fortran 2018 also requires that flag to handle gradually diminishing numbers. One is never to old to learn.

If I particularly, say I want a variable x to be +infinite, what should I do?
Should I do

x = huge(x) + 1.0

Is there better way to make x = + infinite ?

Thanks @Beliavsky , I see, can use things like ieee_positive_inf in intrinsic module ieee_arithmetic. Got it.

You can use the ieee_is_negative() and ieee_is_finite() functions of the module ieee_arithmetic, as I tweeted, with example code

program test_ieee_arithmetic
use, intrinsic :: ieee_arithmetic
implicit none
character (len=20) :: fmt = "(a16,*(l9))"
integer, parameter :: wp = kind(1.0) ! same output for wp = kind(1.0d0)
real(kind=wp)      :: z,vec(6),NaN,t
z = 0.0_wp
t = tiny(z)
vec = [z/z,z/1.0_wp,-z/1.0_wp,1.0_wp/z,-1.0_wp/z,t/10]
print*,ieee_value(0.0,ieee_positive_inf),1.0/z ! 2 ways of geting +Inf
NaN = ieee_value(0.0,ieee_quiet_nan) ! get NaN
print*,"NaN == NaN?",NaN == NaN ! demonstrate that NaN /= NaN
print*
print "(19x,*(a9))","0.0/0.0","0.0/1.0","-0.0/1.0","1.0/0.0","-1.0/0.0","tiny/10"
print fmt,"ieee_is_nan"     ,ieee_is_nan(vec)
print fmt,"ieee_is_negative",ieee_is_negative(vec)
print fmt,"ieee_is_finite"  ,ieee_is_finite(vec)
print fmt,"ieee_is_normal"  ,ieee_is_normal(vec) 
end program test_ieee_arithmetic
! gfortran output:
!         Infinity         Infinity
! NaN == NaN? F
!
!                      0.0/0.0  0.0/1.0 -0.0/1.0  1.0/0.0 -1.0/0.0  tiny/10
!      ieee_is_nan        T        F        F        F        F        F
! ieee_is_negative        F        F        T        F        T        F
!   ieee_is_finite        F        T        T        F        F        T
!   ieee_is_normal        F        T        T        F        F        F
1 Like

An alternative from @sblionel that does not use the ieee_arithmetic module is

program main
implicit none
integer      , parameter :: sp = kind(1.0), dp = kind(1.0d0)
real(kind=sp), parameter :: inftys = real(z'7f800000',kind=sp)
real(kind=dp), parameter :: inftyd = real(z'7FF0000000000000',kind=dp)
print*,inftys,inftyd ! Infinity Infinity
end program main

Gfortran on WSL2 requires the -fno-range-check option to compile it.

1 Like

It seems gfortran has a problem with signaling NaNs. Consider

program test_ieee_arithmetic
  use, intrinsic :: ieee_arithmetic
  implicit none
  integer, parameter :: wp = kind(1.0)
  real(kind=wp)      :: NaN, z
  integer :: inan
  z = 0.
  print *, "         hex value NaN qNaN sNaN"
  NaN = ieee_value(0.0,ieee_quiet_nan) ! get qNaN
  inan = transfer(NaN,inan)
  print '("quiet: ",Z12,3L4)', inan, ieee_is_nan(NaN),is_qnan(NaN),is_snan(NaN)
  NaN = ieee_value(0.0,ieee_signaling_nan) ! get sNaN
  inan = transfer(NaN,inan)
  print '("signal:",Z12,3L4)', inan, ieee_is_nan(NaN),is_qnan(NaN),is_snan(NaN)
  NaN = 0/z  ! get 0/0 NaN
  inan = transfer(NaN,inan)
  print '("0/0:   ",Z12,3L4)', inan, ieee_is_nan(NaN),is_qnan(NaN),is_snan(NaN)
     
contains
  logical function is_qnan(x)
    real(kind=wp), intent(in) :: x
    is_qnan = (ieee_class(x) == ieee_quiet_nan)
  end function is_qnan
  logical function is_snan(x)
    real(kind=wp), intent(in) :: x
    is_snan = (ieee_class(x) == ieee_signaling_nan)
  end function is_snan
end program test_ieee_arithmetic
gfortran output:                     ifort output:
          hex value NaN qNaN sNaN   	       hex value NaN qNaN sNaN
quiet:     FFC00000   T   T   F      quiet:     7FC00000   T   T   F
signal:    FFC00000   T   T   F      signal:    7FA00000   T   F   T
0/0:       FFC00000   T   T   F      0/0:       FFC00000   T   T   F

So gfortran’s ieee_value returns the same bit pattern for both ieee_quiet_nan and ieee_signaling_nan which is then interpreted as a quiet NaN. Checked in vers. 10 and 11, independent of applying/not applying -fsignaling-nans option.

This is very useful, thanks!