无法使用通常的自等价来识别 nvfortran 中的 nan
Cannot use usual self-equivalency to identify nan in nvfortran
在大多数 fortran 编译器中,例如 gfortran,为了识别小的旧 nans,您可以通过进行某种等价性测试来检查,利用 nan 不是自等价的事实。例如,如果 nanny=nan
,那么 (nanny/=nanny)
应该输出 T
。所以,对于下面的代码:
program test_nan
implicit none
real :: nanny,zero=0.0
nanny=zero/zero
print*,nanny
if (nanny/=nanny) then
print*,"found by self-equivalency"
else
print*,"not found by self-equivalency"
end if
if (nanny-1==nanny) then
print*,"found by perpetual transigence"
else
print*,"not found by perpetual transigence"
end if
if (nanny>1000000000000.0) then
print*,"found by big number"
else
print*,"not found by big number"
end if
end program
如果我在 gfortran 和 运行 中编译它,我得到:
NaN
found by self-equivalency
not found by perpetual transigence
not found by big number
但是,对 nvfortran 做同样的事情会得到:
NaN
not found by self-equivalency
not found by perpetual transigence
not found by big number
我可以在 nvfortran 中检查 nans 吗?
自 Fortran 2003 以来,测试 NaN 的标准方法是通过该语言提供的 IEEE 754-1985 支持。下面是一个例子。请注意,测试一个变量是否与自身相等并不是一个好主意,因为优化器通常会删除它——这可能就是您在上面看到的。除以零也会产生实现定义的行为,因此在那之后任何事情都可能发生——下面的代码显示了产生 NaN 的标准方法。
ijb@ijb-Latitude-5410:~/work/stack$ cat nan.f90
program test_nan
Use, Intrinsic :: ieee_arithmetic, Only : ieee_signaling_nan, &
ieee_support_nan, ieee_value, ieee_is_nan
implicit none
real :: nanny
If( .Not. ieee_support_nan( nanny ) ) Then
Write( *, * ) 'Processor does not support NaNs'
Stop
End If
nanny = ieee_value( nanny, ieee_signaling_nan )
If( ieee_is_nan( nanny ) ) Then
Write( *, * ) 'Nanny is a Nan'
Else
Write( *, * ) 'Nanny is NOT a Nan, she is ', nanny
End If
nanny = 3.0
If( ieee_is_nan( nanny ) ) Then
Write( *, * ) 'Nanny is a Nan'
Else
Write( *, * ) 'Nanny is NOT a Nan, she is ', nanny
End If
end program test_nan
ijb@ijb-Latitude-5410:~/work/stack$ gfortran --version
GNU Fortran (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ijb@ijb-Latitude-5410:~/work/stack$ gfortran -std=f2018 -Wall -Wextra -fcheck=all -O -Wuse-without-only nan.f90 -o nan
ijb@ijb-Latitude-5410:~/work/stack$ ./nan
Nanny is a Nan
Nanny is NOT a Nan, she is 3.00000000
ijb@ijb-Latitude-5410:~/work/stack$
在大多数 fortran 编译器中,例如 gfortran,为了识别小的旧 nans,您可以通过进行某种等价性测试来检查,利用 nan 不是自等价的事实。例如,如果 nanny=nan
,那么 (nanny/=nanny)
应该输出 T
。所以,对于下面的代码:
program test_nan
implicit none
real :: nanny,zero=0.0
nanny=zero/zero
print*,nanny
if (nanny/=nanny) then
print*,"found by self-equivalency"
else
print*,"not found by self-equivalency"
end if
if (nanny-1==nanny) then
print*,"found by perpetual transigence"
else
print*,"not found by perpetual transigence"
end if
if (nanny>1000000000000.0) then
print*,"found by big number"
else
print*,"not found by big number"
end if
end program
如果我在 gfortran 和 运行 中编译它,我得到:
NaN
found by self-equivalency
not found by perpetual transigence
not found by big number
但是,对 nvfortran 做同样的事情会得到:
NaN
not found by self-equivalency
not found by perpetual transigence
not found by big number
我可以在 nvfortran 中检查 nans 吗?
自 Fortran 2003 以来,测试 NaN 的标准方法是通过该语言提供的 IEEE 754-1985 支持。下面是一个例子。请注意,测试一个变量是否与自身相等并不是一个好主意,因为优化器通常会删除它——这可能就是您在上面看到的。除以零也会产生实现定义的行为,因此在那之后任何事情都可能发生——下面的代码显示了产生 NaN 的标准方法。
ijb@ijb-Latitude-5410:~/work/stack$ cat nan.f90
program test_nan
Use, Intrinsic :: ieee_arithmetic, Only : ieee_signaling_nan, &
ieee_support_nan, ieee_value, ieee_is_nan
implicit none
real :: nanny
If( .Not. ieee_support_nan( nanny ) ) Then
Write( *, * ) 'Processor does not support NaNs'
Stop
End If
nanny = ieee_value( nanny, ieee_signaling_nan )
If( ieee_is_nan( nanny ) ) Then
Write( *, * ) 'Nanny is a Nan'
Else
Write( *, * ) 'Nanny is NOT a Nan, she is ', nanny
End If
nanny = 3.0
If( ieee_is_nan( nanny ) ) Then
Write( *, * ) 'Nanny is a Nan'
Else
Write( *, * ) 'Nanny is NOT a Nan, she is ', nanny
End If
end program test_nan
ijb@ijb-Latitude-5410:~/work/stack$ gfortran --version
GNU Fortran (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ijb@ijb-Latitude-5410:~/work/stack$ gfortran -std=f2018 -Wall -Wextra -fcheck=all -O -Wuse-without-only nan.f90 -o nan
ijb@ijb-Latitude-5410:~/work/stack$ ./nan
Nanny is a Nan
Nanny is NOT a Nan, she is 3.00000000
ijb@ijb-Latitude-5410:~/work/stack$