我想编译一个启用了gfortran和-O3 -ffast-math的程序,因为它可以大大提高性能。我很困惑,gfortran的isnan()捕获了一些NaN,但不是全部。看完之后

Checking if a double (or float) is NaN in C++
how do I make a portable isnan/isinf function
Negative NaN is not a NaN?

我给人的印象是,即使启用了快速数学功能,人们也可以通过位错检查C中的NaN。但是,这让我感到迷惑


可能会导致依赖于的确切实现的程序的输出不正确
数学函数的IEEE或ISO规则/规范。


根据gcc 4.7.2的手册页。那么,如果没有按照IEEE标准表示数字,您怎么知道要检查哪一位呢?如果知道的话,您将如何在Fortran 95/03/08中实现它?

不要费心发布(x \= x)或类似的解决方案,这些解决方案取决于IEEE规则。它们给出与isnan()相同的结果。我也知道-ffpe-trap=invalid,zero,overflow,但是不想停止该程序。如果有帮助,我的操作系统是64位LinuxMint14。如果在Fortran中无法实现,那么防水C解决方案也不错。

最佳答案

首先,我要指出的是,gfortran 4.9支持IEEE_arithmetic模块。但是,我不能依靠gfortran 4.9,它太新了。

我实际上在实践中使用的是将检查x/=x移至没有-ffast-math并且没有链接时间优化的情况下编译的过程:

module ieee_arithmetic
  !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
  use iso_fortran_env

  !common extension isnan may actually fail with optimizations above
!   intrinsic isnan

  interface ieee_is_nan
    module procedure ieee_is_nan_real32
    module procedure ieee_is_nan_real64
  end interface

contains
  logical function ieee_is_nan_real32(x) result(res)
    real(real32), intent(in) :: x

    res = x /= x
  end function

  logical elemental function ieee_is_nan_real64(x) result(res)
    real(real64), intent(in) :: x

    res = x /= x
  end function

end module


它在单独的文件中,然后在不使用-Ofast--ffast-math-flto的情况下进行编译。当心缺少内联会严重降低性能。

关于optimization - 是否可以在gfortran -O3 -ffast-math中使isnan()工作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15944614/

10-12 06:06