2011-02-15 97 views
6

在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 

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

回答

7

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

如果您在表达式中使用特殊的值(我不认为这通常是可取的),你应该仔细注意你的编译器如何处理他们,你可能会得到一些意外的结果。

0

我不会依赖于编译器,支持IEEE标准和做几乎你做了什么,有两个变化:

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

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

+2

`真实* 8`和'双precision`(`1.d0`)不necesarilly同实样。当然,是否使用单精度或双精度不是个人偏好问题,而是数学论证和测试。 – 2014-09-23 15:04:50

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 

对复杂变量也很好地工作。

+0

如果您不启用FPE捕获,它将在符合IEEE标准的机器上工作。但是,如果你与无穷无关的工作,这将是愚蠢的。 – 2014-09-23 15:06:19

0

这似乎适用于我。 定义参数

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

然后,如果测试使用了进去。

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 &运行编译,我得到

sng = inf 
dbl1 = inf 
dbl2 = inf