DAMASK_EICMD/documentation/Code/Fortran/nan.f90

95 lines
3.5 KiB
Fortran

program nantest
! This file: http://ftp.aset.psu.edu/pub/ger/fortran/hdk/nan.f90
!
!====NAN.F90 illustrates what works and what doesn't when
! detecting a NaN. All but the Fortran 2003 IEEE_IS_NAN are not
! Standard Fortran.
!
! Platforms: Windows 9x/Me/NT/2000, AIX 4.3, Linux
! Compiler Notes:
! Compaq Visual Fortran 6.6C with default
! fpe settings (/fpe:3 /nocheck) and /OPTIMIZE:0
! (ISNAN is an Elemental Intrinsic Function)
! Options /fpe:0 /traceback will cause this
! program to stop with error message,
! James Giles points out that in order to actually print
! minus zero from CVF, you have to compile with the
! /assume:minus0 option.
!
! AIX XLF90 without optimization.
! (ISNAN is part of a BOS Runtime C library;
! thus ISNAN must be declared LOGICAL.)
!
! Linux Intel IFORT, use: -O0 (no optimization) and
! -assume minus0
!
! g95 supports ieee_is_nan elemental function.
!
!
! Author: hdkLESS at SPAM psu dot edu
! Date: March, 2002, January 2005, August 2006.
!
! References:
! http://www.psc.edu/general/software/packages/ieee/ieee.html
! http://homepages.borland.com/efg2lab/Mathematics/NaN.htm
! http://en.wikipedia.org/wiki/NaN
!
logical :: ISNAN
integer :: i
integer, Dimension (6) :: Iy
real, Dimension (6) :: y
integer :: IPInf, IMinf, IMZero
real :: PInf, MInf, MZero, DivNan
Character (Len=10), Dimension(6) :: NType
data NType/'+Infinity','-Infinity','-0', 'NaN','NaN','0/0'/
data IPInf/B'01111111100000000000000000000000'/ ! +Infinity
data IMInf/B'11111111100000000000000000000000'/ ! -Infinity
data IMZero/B'10000000000000000000000000000000'/ ! -0
data Iy(1)/B'01111111100000000000000000000000'/ ! +Infinity
data Iy(2)/B'11111111100000000000000000000000'/ ! -Infinity
data Iy(3)/B'10000000000000000000000000000000'/ ! -0
data Iy(4)/B'01111111100000100000000000000000'/ ! NaN
data Iy(5)/B'11111111100100010001001010101010'/ ! NaN
data Iy(6)/B'11111111110000000000000000000000'/ ! 0/0
PInf = transfer(IPinf,Pinf)
Minf = transfer(IMinf,Minf)
MZero = transfer(IMZero,MZero)
Y = transfer(IY,Y)
! Some debug options for some compilers may flag the following
! zero/zero as an exception. If so, comment out the next two lines.
DivNan=0
y(6)=DivNan/DivNan
Do i=1,6
print *, 'Test#',i,' ->',NType(i)
if (y(i).eq.PInf) print *, 'Y = Plus Infinity'
if (y(i).eq.MInf) print *, 'Y = Minus Infinity'
if (y(i).eq.Mzero) print *, 'Y = Minus Zero'
print *, 'y(Test#)=',y(i)
print *, 'Testing each of three NaN detection methods:'
! EQV -> true iff both A and B are True or iff both A and B are False.
if( (y(i) > 0.0) .EQV. (y(i) <= 0.0)) then
print *, '1) (y(Test#) > 0.0) .EQV. (y(Test#) <= 0.0)'
end if
if (y(i)/=y(i)) then
print *, '2) (y(Test#)/=(y(Test#))'
end if
! If ISNAN is available for a specific compiler, uncomment the
! following 3 lines.
! if (ISNAN(y(i))) then
! print *, '3) ISNAN(y(Test#))'
! end if
! if Fortran 2003 IEEE floating-point exception handling is available
! uncomment the following 4 lines
! use ieee_arithmetic
! if (ieee_is_nan(y(i))) then
! print *, '4) ieee_is_nan(y(Test#))'
! end if
print *, ' '
End Do
end program nantest