I read real valued data from an input file with list directed input. What is the best way to detect a NaN via iostat=iostatus?
As an example for the input for a large program I need to read a file like:
1 NaN 1.0
2 nan 2.0
where there are occasionally "NaN"s instead of real valued numbers.
with READ(ird, *, iostat=iostatus) nr, r1, r2
no iostatus is flagged for gfortran 7.4.0 on UBUNTU!
Apparently the input error is treated as a quiet NaN instead of a signalling NaN. The gfortran compiler options do not seem to provide an option to turn this into a signalling NaN. The fortran standard at https://j3-fortran.org/doc/year/18/18-007r1.pdf does not specify treatment of a Nan in list directed input.
In section 13.7.2.3.2 there is info for formatted input, and it specifically states that the Nan on input is treated as a quiet NaN.
I found a documentation on the NAG compiler and it states explicitely that a NaN on input is never flagged as a signalling NaN.
The philosophy behind these decisions in the standard beats me. I would have expected that this shoud be an error.
If the line is changed to:
read(ird, *, err=10, iostat=iostatus) nr, r1, r2
10 continue
the iostatus changes to +5001 ! But I do not really want to resort back to the ancient err= clause.
I am aware that I could read the line into a character string, analyze the string for the presence of any "NaN" and proceed. I could as in the example analyse ieee_is_nan(). That seems however unnecessarily tedious given the iostat= clause.
So is there a compiler option that I missed ?
PROGRAM main
USE ieee_arithmetic
IMPLICIT NONE
INTEGER, PARAMETER :: IRD = 12
INTEGER :: iostatus
REAL :: r1 = -1.0, r2 = -1.0
INTEGER :: nr = 0
CHARACTER(LEN=1024) :: line = ' '
OPEN(UNIT=IRD,FILE='data.data', STATUS='old')
READ(IRD, *, IOSTAT=iostatus, IOMSG=line) nr, r1, r2
WRITE(*,*) iostatus, nr, r1, r2, ieee_is_nan(r1), line(1:LEN_TRIM(line))
r1 = -1.0
r2 = -1.0
READ(IRD, ERR=10, IOSTAT=iostatus, IOMSG=line) nr, r1, r2
10 CONTINUE
WRITE(*,*) iostatus, nr, r1, r2, ieee_is_nan(r1), line(1:LEN_TRIM(line))
CLOSE(UNIT=IRD)
END PROGRAM main
The output of my program is: (Shortened insignificant digits and blanks)
0 1 NaN 1.00 T
5001 1 -1.00 -1.00 F
Missing format for FORMATTED data transfer
At the first read iostatus is set to 0, while on the second read its set to 5001!