我从具有列表定向输入的输入文件中读取实值数据。通过iostat=iostatus
检测NaN的最佳方法是什么?
作为输入大型程序的示例,我需要读取一个文件,例如:
1 NaN 1.0
2 nan 2.0
有时用“ NaN”代替实际值。
与READ(ird, *, iostat=iostatus) nr, r1, r2
UBUNTU上的gfortran 7.4.0没有标记为iostatus!
显然,输入错误被视为安静的NaN而不是信令NaN。 gfortran编译器选项似乎没有提供将其转换为信令NaN的选项。 fortran标准位于 https://j3-fortran.org/doc/year/18/18-007r1.pdf 没有在列表定向输入中指定对Nan的处理。
在13.7.2.3.2节中,有关于格式化输入的信息,并特别指出,输入中的Nan被视为安静的NaN。
我找到了有关NAG编译器的文档,它明确指出输入中的NaN永远不会标记为信号NaN。
这些决策背后的哲学使我震惊。我本以为这应该是个错误。
如果该行更改为:
read(ird, *, err=10, iostat=iostatus) nr, r1, r2
10 continue
iostatus变为+5001!但是我真的不想求助于古老的err=
条款。
我知道我可以将行读入字符串中,分析字符串中是否存在任何“ NaN”,然后继续。我可以像示例中那样分析ieee_is_nan()
。但是,考虑到iostat=
子句,这似乎不必要地乏味。
那么有没有我错过的编译器选项?
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
我的程序的输出为:(数字和空格都缩短了)
0 1 NaN 1.00 T
5001 1 -1.00 -1.00 F
Missing format for FORMATTED data transfer
第一次读取时iostatus设置为0,而第二次读取时iostatus设置为5001!