2011-02-15 139 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