Positive/Negative Fortran 中的无穷大常量

Positive/Negative Infinity Constants in Fortran

如何在 Fortran 2008 中获得负无穷大和正无穷大的常量(我想是 parameters)?我尝试了以下代码:

program inf
  use, intrinsic :: ieee_arithmetic

  real(8), parameter :: inf_pos = ieee_value(0d0, ieee_positive_inf)
  real(8), parameter :: inf_neg = ieee_value(0d0, ieee_negative_inf)
end program inf

但是,我收到以下错误:

$ gfortran inf.f08
inf.f08:4:22:

   real(8) :: inf_pos = ieee_value(0d0, ieee_positive_inf)
                  1
Error: Function ‘ieee_value’ in initialization expression at (1) must be an intrinsic function
inf.f08:5:22:

   real(8) :: inf_neg = ieee_value(0d0, ieee_negative_inf)
                  1
Error: Function ‘ieee_value’ in initialization expression at (1) must be an intrinsic function

尽管文档另有说明,但 gfortran 似乎认为 ieee_value() 不是固有的。

有没有办法得到我想做的事情?

我想出的有点不雅的解决方案是简化定义函数,它总是 return 正无穷大和负无穷大

program inf
  use, intrinsic :: ieee_arithmetic

  print *, inf_pos()
  print *, inf_neg()

contains
  pure function inf_pos() result(r)
    real(8) :: r
    r = ieee_value(0d0, ieee_positive_inf)
  end function inf_pos

  pure function inf_neg() result(r)
    real(8) :: r
    r = ieee_value(0d0, ieee_negative_inf)
  end function inf_neg
end program inf

我会先看看为什么你不能使用 ieee_value 来给你想要的命名常量赋值,然后我会告诉你坏消息。两者都很有趣(对我来说)。

ieee_value 不是 内在过程。这是一个内部模块中的过程,但正如 Fortran 2008 标准注释(注释 13.25):

The types and procedures defined in standard intrinsic modules are not themselves intrinsic.

gfortran 正确地注意到 ieee_value 不能用于初始化(常量)表达式。

现在,如果您需要使用 "infinite" 值初始化命名常量,则有不可移植的选项:1.

  • 类似于,您可以计算出所需的位模式并使用transfer;
  • 进行初始化
  • 你可能able写了一个"overflowing"初始化表达式。

您可以使用构建系统和预处理器解决此问题的不可移植性。

总而言之,您可能不需要无限命名常量。 IEEE 模块很容易为 "is this value infinite?" 或 "set this value to be infinite" 提供过程。您的编译器可能还具有 "initialize variable to infinity" 作为编译时选项。


1 在初始化表达式之外使用 ieee_value 的限制要宽松得多。

以下将产生 + 和 - Infinity,但是,必须执行并且不接受直接在变量声明中作为初始化:

program testinf
implicit none
double precision :: x, xiplus, xineg   
x       = HUGE(x)
xiplus  = 2 * x     ! yields +Infinity
xineg   =-2 * x     ! yields -Infinity
write(*,*)x , xiplus, xineg 
end program testinf