Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Fortran语言中的无穷大_Fortran_Infinity - Fatal编程技术网

Fortran语言中的无穷大

Fortran语言中的无穷大,fortran,infinity,Fortran,Infinity,在Fortran中将变量设置为+无穷大最安全的方法是什么?目前我正在使用: 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 但我想知道是否有更好的方法?

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

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

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

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

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
如果您在表达式中使用异常值(我认为这通常是不可取的),您应该仔细注意编译器如何处理它们,否则可能会得到一些意外的结果

如果编译器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

我不会依赖编译器来支持IEEE标准,也不会像您那样做,但有两个变化:

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

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


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

    对复杂变量也很有效。

    这似乎对我很有效。 定义一个参数

    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
    

    real*8
    double-precision
    1.d0
    )不一定是完全相同的实数类型。当然,使用单精度还是双精度不是个人偏好的问题,而是数学论证和测试的问题。如果不启用FPE捕获,它将在符合IEEE标准的机器上工作。但如果你处理无穷大,那么这样做是愚蠢的,至少在gfortran中是不行的。它会引发编译器错误。
    sng = inf
    dbl1 = inf
    dbl2 = inf