bij*_*ncn 5 optimization fortran nan gfortran ieee-754
我想用 gfortran 编译一个程序并-O3 -ffast-math
启用它,因为它可以提供很好的性能提升。我很困惑,gfortranisnan()
捕获了一些 NaN,但不是全部。看完之后
检查 C++ 中的 double(或 float)是否为 NaN
如何制作可移植的 isnan/isinf 函数
负 NaN 不是 NaN?
我的印象是,即使启用了快速数学,人们也可以通过位调整来检查 C 中的 NaN。然而,这让我感到困惑,因为快速数学
可能会导致依赖于数学函数的 IEEE 或 ISO 规则/规范的精确实现的程序输出不正确。
根据 gcc 4.7.2 的手册页。那么,如果数字没有按照 IEEE 标准表示,您如何知道要检查哪一位呢?如果您知道它,您将如何在 Fortran 95/03/08 中实现它?
不要费心发布(x \= x)
依赖于 IEEE 规则的类似解决方案。他们给出的结果与 相同isnan()
。我也知道-ffpe-trap=invalid,zero,overflow
,但不想停止该程序。如果有帮助的话,我的操作系统是 64 位 LinuxMint 14。如果 Fortran 中不可能,防水的 C 解决方案也很好。
首先我要指出的是,gfortran 4.9 支持 IEEE_arithmetic 模块。然而,该模块中的过程中的检查可以被优化掉并且应用相同的逻辑。
然而,我不能依赖2014年的GCC 4.9,它太新鲜了。我使用了以下内容。
当我不得不使用时,x/=x
我将检查x/=x
移至一个在没有链接时间优化的情况下编译的过程-ffast-math
:
module my_is_nan_mod
!poor man's replacement for the intrinsic module
!do not use if the compiler supports the F2003 version
!make sure not to use fast math optimizations when compiling
use iso_fortran_env
!the common extension isnan() may actually fail with fast math optimizations
interface my_is_nan
module procedure my_is_nan_real32
module procedure my_is_nan_real64
end interface
contains
logical function my_is_nan_real32(x) result(res)
real(real32), intent(in) :: x
res = x /= x
end function
logical elemental function my_is_nan_real64(x) result(res)
real(real64), intent(in) :: x
res = x /= x
end function
end module
Run Code Online (Sandbox Code Playgroud)
它位于一个单独的文件中,然后在不带-Ofast
和--ffast-math
不带-flto
. 请注意,缺少内联可能会导致性能严重下降。
-ffast-math
编译器看到后x/=x
,决定它不可能为真,并将表达式优化为.false.
。