Fortran中的正/负无限常量

时间:2018-05-30 18:11:09

标签: floating-point fortran gfortran ieee-754

我怎样才能获得Fortran 2008中的负数和正数无穷大的常数(或parameter s)?我尝试了以下代码:

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()不是内在的。

有没有得到我想要做的事情?

3 个答案:

答案 0 :(得分:3)

我首先看一下为什么你不能使用ieee_value给出你想要的命名常量的值,然后我会给出坏消息。两者都很有趣(对我而言)。

ieee_value 不是内在程序。它是内在模块中的一个过程,但是作为Fortran 2008标准注释(注13.25):

  

标准内在模块中定义的类型和过程本身并不是固有的。

gfortran是正确的,注意ieee_value可能不会用在初始化(常量)表达式中。

现在,如果您需要使用“无限”值初始化命名常量,则存在非可移植选项: 1

  • this question about NaNs类似,您可以计算出所需的位模式并使用transfer初始化;
  • 你可能会able写一个“溢出”的初始化表达式。

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

所有人都说,你可能不需要有一个无限的命名常数。 IEEE模块可以轻松地为“这个值无限吗?”或“将此值设置为无限”提供程序。您的编译器也可能将“初始化变量设置为无穷大”作为编译时选项。

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

答案 1 :(得分:1)

我提出的有点不优雅的解决方案是简化定义函数,这些函数总是返回正负无穷大

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

答案 2 :(得分:0)

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

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