【问题标题】:division by zero doesn't work with ieee_arithmetic in gfortran 5.4除以零不适用于 gfortran 5.4 中的 ieee_arithmetic
【发布时间】:2017-08-17 20:21:06
【问题描述】:

我在运行gfortran 5.4.0 版的Linux 机器上使用ieee_arithmetic 和Fortran。

我在尝试初始化 InfNaN 的值时遇到除零错误。

ieee_arithmetic 似乎没有问题,因为在文件的其他地方我可以成功调用 ieee_is_finite() 而没有问题。

我认为ieee_arithmetic 允许在这些特定情况下使用除零,但我一定遗漏了一些东西。以下是代码示例:

module rcrlib_gnu
    use, intrinsic :: ieee_arithmetic ! requires gfortran version 5.0 or higher
    implicit none
    integer, parameter :: SP=kind(1.0), DP=selected_real_kind(9,99)
    integer, parameter :: stderr=0
    public SP, DP, is_finite, stderr, initialize

contains

subroutine initialize(infty,nan)
    real(kind=DP), intent(out) :: infty, nan
    infty = 1.0_dp/0.0_dp ! huge(1.0_dp)
    nan = 0.0_dp/0.0_dp
end subroutine initialize

elemental function is_finite(x)
    real(kind=DP), intent(in) :: x
    logical :: is_finite
    is_finite = ieee_is_finite(x) ! This call requires "ieee_arithmetic"
end function is_finite 

end module rcrlib_gnu

我似乎遗漏了一些基本的东西,所以我将不胜感激。

要重现错误,请将上面的代码 sn -p 保存为rcrlib_gnu_example.f90,然后执行以下行: gfortran -o rcr rcrlib_gnu_example.f90

产生的错误输出是

rcrlib_gnu_example.f90:12:18:

     infty = 1.0_dp/0.0_dp ! huge(1.0_dp)
                  1
Error: Division by zero at (1)
rcrlib_gnu_example.f90:13:16:

     nan = 0.0_dp/0.0_dp
                1
Error: Division by zero at (1)

【问题讨论】:

  • 类似的帖子herehere 已经询问过这个问题,但不是对我的查询的直接回答。 This page 建议除以零产生+InfNaN in ieee_arithmetic
  • 它不是 Fortran 90。它是 Fortran 2003 或更高版本。旧的 Fortran 90 中没有 ieee_arithmetic。
  • 向我们展示导致错误或意外行为的代码。见minimal reproducible example。我们必须能够重现问题。
  • 请注意,如果您想要的话,除了除法之外,还有其他方法可以获得 InfNaN。转换大于最大有限浮点数 + 半个 ULP 的十进制表示会产生 Inf,一旦你有 Inf,你就可以得到 NaNInf - Inf。 (不确定这是否有用,但我想我应该指出它以防万一。)

标签: fortran gfortran


【解决方案1】:

感谢Pascal Cuoq,我解决了这个问题。

编译的initialize子程序的版本如下:

subroutine initialize(infty,nan)
    real(kind=DP), intent(out) :: infty, nan
    infty = huge(1.0_dp)+100
    nan = infty-infty
end subroutine initialize

所以基本上将infinity设置为最大浮点数加100,然后将NaN设置为无穷大与自身的差。

感谢大家对我缺乏 FORTRAN 经验的快速响应和耐心。

【讨论】:

  • 既然您可以访问 IEEE 模块,为什么这种方法比使用 ieee_value() 更好?特别是,当设置了溢出的暂停模式时分配给infty会发生什么?
  • @francescalus 这可能不是更好的方法,我不确定您对暂停模式的担忧。上面的解决方案似乎有效(至少在我的机器上编译),但你的观点很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-13
  • 2017-11-04
  • 2018-07-19
  • 1970-01-01
  • 2019-12-23
  • 1970-01-01
相关资源
最近更新 更多