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
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.
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!