11

在 Fortran 中将变量设置为 +Infinity 的最安全方法是什么?目前我正在使用:

program test
  implicit none
  print *,infinity()
contains
  real function infinity()
    implicit none
    real :: x
    x = huge(1.)
    infinity = x + x
  end function infinity
end program test

但我想知道是否有更好的方法?

4

5 回答 5

11

如果您的编译器支持ISO TR 15580 IEEE 算术,它是所谓的 Fortran 2003 标准的一部分,那么您可以使用来自 ieee_* 模块的过程。

PROGRAM main

  USE ieee_arithmetic

  IMPLICIT NONE

  REAL :: r

  IF (ieee_support_inf(r)) THEN
    r = ieee_value(r,  ieee_negative_inf)
  END IF

  PRINT *, r

END PROGRAM main
于 2011-02-16T06:15:01.837 回答
1

我不会依赖编译器来支持 IEEE 标准并做你所做的几乎所有事情,但有两个变化:

  1. 我不会添加huge(1.)+huge(1.),因为在某些编译器上,您最终可能会得到-huge(1.)+1--- 这可能会导致内存泄漏(不知道原因,但可以这么说,这是一个实验事实)。

  2. 您在real这里使用类型。我个人更喜欢将我所有的浮点数保留为real*8,因此所有浮点常量都用 限定d0,如下所示huge(1.d0):当然,这不是规则;有些人更喜欢同时使用real-s 和real*8-s。

于 2011-02-16T10:50:19.657 回答
1

我不确定下面的解决方案是否适用于所有编译器,但它是一种很好的数学方法,可以像 -log(0) 一样达到无穷大。

program test
  implicit none
  print *,infinity()
contains
  real function infinity()
    implicit none
    real :: x
    x = 0
    infinity=-log(x)
  end function infinity
end program test

也适用于复杂的变量。

于 2014-09-23T13:35:12.760 回答
0

我不知道最安全的方法,但我可以为您提供另一种方法。我学会了这样做:

PROGRAM infinity
  IMPLICIT NONE
  INTEGER :: inf
  REAL :: infi
  EQUIVALENCE (inf,infi) !Stores two variable at the same address
  DATA inf/z'7f800000'/ !Hex for +Infinity
  WRITE(*,*)infi
END PROGRAM infinity

如果您在表达式中使用异常值(我认为这通常是不可取的),您应该特别注意编译器如何处理它们,否则您可能会得到一些意想不到的结果。

于 2011-02-16T00:42:16.970 回答
-1

这似乎对我有用。定义参数

double precision,parameter :: inf = 1.d0/0.d0

然后在 if 测试中使用它。

  real :: sng
  double precision :: dbl1,dbl2

  sng = 1.0/0.0
  dbl1 = 1.d0/0.d0
  dbl2 = -log(0.d0)

  if(sng == inf) write(*,*)"sng = inf"
  if(dbl1 == inf) write(*,*)"dbl1 = inf"
  if(dbl2 == inf) write(*,*)"dbl2 = inf"
  read(*,*)

当用 ifort & run 编译时,我得到

sng = inf
dbl1 = inf
dbl2 = inf
于 2015-02-02T15:59:27.770 回答