在Fortran 90中的NaN问题

Joe*_*man 3 fortran90 intel-fortran

我意识到,如果你写

    Real (Kind(0.d0))::x,y
    x = sqrt(-1.d0)
    y = sqrt(-1.d0)
    if (x == y) then
       write(*,*)'yep, they are equals', x
    endif
Run Code Online (Sandbox Code Playgroud)

它使用ifort编译好.但没有写任何内容,条件总是错误的,你注意到了吗?为什么会这样?

Jon*_*rsi 12

NaN表示不是数字,并且由于计算可以给出该结果有许多不同的原因,因此它们通常不会对自己进行比较.如果你想进行纳米测试,那么支持f2003标准的fortran编译器(大多数编译器的最新版本)都ieee_is_nanieee_arithmetic模块中:

program testnan
    use ieee_arithmetic

    real (kind=kind(0.d0)) :: x,y,z

    x = sqrt(-1.d0)
    y = sqrt(-1.d0)
    z = 1.d0

    if ( ieee_is_nan(x) ) then
       write(*,*) 'X is NaN'
    endif
    if ( ieee_is_nan(y) ) then
       write(*,*) 'Y is NaN'
    endif
    if ( ieee_is_nan(x) .and. ieee_is_nan(y) ) then
       write(*,*) 'X and Y are NaN'
    endif

    if ( ieee_is_nan(z) ) then
       write(*,*) 'Z is NaN, too'
    else
       write(*,*) 'Z is a number'
    endif

end program testnan
Run Code Online (Sandbox Code Playgroud)

编译并运行此程序给出

ifort -o nan nan.f90

 X is NaN
 Y is NaN
 X and Y are NaN
 Z is a number
Run Code Online (Sandbox Code Playgroud)

不幸的是,gfortran仍然没有实现ieee_arithmetic写作时间,所以使用gfortran你必须使用非标准isnan.

  • 我通常使用 `if(x /= x)` 作为我的 NaN 检查来代替 `isnan` 和 `ieee_is_nan` 调用。只是另一种选择,我想。 (2认同)