2015-09-17 234 views
0

我在Fortran IV中有需要運行的代碼。我被告知嘗試在Fortran 77中進行編譯並修復錯誤。所以我用.f擴展名命名該文件,並嘗試用gfortran進行編譯。我得到了一個錯誤指的是Fortran IV標準功能如下複製:使用Fortran 77編譯器編譯Fortran IV代碼

abel.f:432.24: 

     REAL FUNCTION DGDT*8(IX,NV,XNG,FNG,GNG,X) 
         1 
Error: Expected formal argument list in function definition at (1) 

由於我不是太熟悉Fortran我會很感激,如果有人能告訴我如何解決這個問題。

 REAL FUNCTION DGDT*8(IX,NV,XNG,FNG,GNG,X)       AAOK0429 
C                  AAOK0430 
C  THIS SUBROUTINE COMPUTES THE VALUE OF THE DERIVATIVE OF THE  AAOK0431 
C  G-FUNCTION FOR A SLIT TRANSMISSION FUNCTION GIVEN BY A   AAOK0432 
C  PIECE-WISE CUBIC SPLINE , WHOSE PARAMETERS ARE     AAOK0433 
C  CONTAINED IN XNG,FNG AND GNG.          AAOK0434 
C                  AAOK0435 
     IMPLICIT REAL*8(A-H,O-Z)           AAOK0436 
C                  AAOK0437 
C  ALLOWABLE ROUNDING ERROR ON POINTS AT EXTREAMS OF KNOT RANGE  AAOK0438 
C  IS 2**IEPS*MAX(!XNG(1)!,!XNG(NV)!).        AAOK0439 
     INTEGER*4 IFLG/0/,IEPS/-50/          AAOK0440 
     DIMENSION XNG(1),FNG(1),GNG(1)         AAOK0441 
C                  AAOK0442 
C  TEST WETHER POINT IN RANGE.          AAOK0443 
     IF(X.LT.XNG(1)) GO TO 990           AAOK0444 
     IF(X.GT.XNG(NV)) GO TO 991          AAOK0445 
C                  AAOK0446 
C  ESTIMATE KNOT INTERVAL BY ASSUMING EQUALLY SPACED KNOTS.  AAOK0447 
    12 J=DABS(X-XNG(1))/(XNG(NV)-XNG(1))*(NV-1)+1      AAOK0448 
C  ENSURE CASE X=XNG(NV) GIVES J=NV-1        AAOK0449 
     J=MIN0(J,NV-1)             AAOK0450 
C  INDICATE THAT KNOT INTERVAL INSIDE RANGE HAS BEEN USED.   AAOK0451 
     IFLG=1               AAOK0452 
C  SEARCH FOR KNOT INTERVAL CONTAINING X.       AAOK0453 
     IF(X.LT.XNG(J)) GO TO 2           AAOK0454 
C  LOOP TILL INTERVAL FOUND.          AAOK0455 
    1 J=J+1                AAOK0456 
    11 IF(X.GT.XNG(J+1)) GO TO 1           AAOK0457 
     GO TO 7               AAOK0458 
    2 J=J-1                AAOK0459 
     IF(X.LT.XNG(J)) GO TO 2           AAOK0460 
C                  AAOK0461 
C  CALCULATE SPLINE PARAMETERS FOR JTH INTERVAL.     AAOK0462 
    7 H=XNG(J+1)-XNG(J)             AAOK0463 
     Q1=H*GNG(J)              AAOK0464 
     Q2=H*GNG(J+1)              AAOK0465 
     SS=FNG(J+1)-FNG(J)            AAOK0466 
     B=3D0*SS-2D0*Q1-Q2            AAOK0467 
     A=Q1+Q2-2D0*SS             AAOK0468 
C                  AAOK0469 
C  CALCULATE SPLINE VALUE.           AAOK0470 
    8 Z=(X-XNG(J))/H             AAOK0471 
C  TF=((A*Z+B)*Z+Q1)*Z+FNG(J)          AAOK0472 
C  TG=((3.*A*Z+2.*B)*Z+Q1)/H           AAOK0473 
C  DGDT=(TG-TF/X)/X             AAOK0474 
     DGDT=(3.*A*Z*Z+2.*B*Z+Q1)/H          AAOK0475 
     RETURN               AAOK0476 
C  TEST IF X WITHIN ROUNDING ERROR OF XNG(1).      AAOK0477 
    990 IF(X.LE.XNG(1)-2D0**IEPS*DMAX1(DABS(XNG(1)),DABS(XNG(NV)))) GO AAOK0478 
    1 TO 99               AAOK0479 
     J=1                AAOK0480 
     GO TO 7               AAOK0481 
C  TEST IF X WITHIN ROUNDING ERROR OF XNG(NV).      AAOK0482 
    991 IF(X.GE.XNG(NV)+2D0**IEPS*DMAX1(DABS(XNG(1)),DABS(XNG(NV)))) GO AAOK0483 
    1 TO 99               AAOK0484 
     J=NV-1               AAOK0485 
     GO TO 7               AAOK0486 
    99 IFLG=0               AAOK0487 
C  FUNCTION VALUE SET TO ZERO FOR POINTS OUTSIDE THE RANGE.  AAOK0488 
     DGDT=0D0               AAOK0489 
     RETURN               AAOK0490 
     END                AAOK0491 
+3

你們的神明,必須有更多現代的代碼來做到這一點!我不知道答案,但知情的快速破解(所以哈克它使我不寒而慄,建議它)是將函數decl改變爲Real * 8函數dgdt(...) –

+1

不是F77,從來沒有Fortran - 真實* 8從來沒有任何標準的任何部分,這就是爲什麼我打了個寒戰(認識我的人會採取諺語)。 –

+0

最後我在說 - 誰知道? Real * 8不是由Fortran標準定義的,因此誰知道給定代碼中給定編譯器將如何理解這些字符。標準允許所有擴展之後,它的解釋沒有定義。 –

回答

2

這看起來不那麼糟糕。現代編譯器仍然接受real*8語法,雖然它不是標準的。所以,你應該(如前所述)與

REAL*8 FUNCTION DGDT(IX,NV,XNG,FNG,GNG,X)       AAOK0429 

成功地利用我使用gfortran -c DGDT.f 4.6.2 gfortran爲編譯更換線

REAL FUNCTION DGDT*8(IX,NV,XNG,FNG,GNG,X)       AAOK0429 

祝你好運,並在尋找其他問題。僅僅因爲代碼編譯確實是而不是,這意味着它的運行方式與它的設計方式相同!

0

不是一個真正的答案,請參閱羅斯的答案。但我無法忍受固定形式的要求。下面是該代碼可能會看起來像F90配備了免費的形式:

function DGDT(IX, NV, XNG, FNG, GNG, X) 
    ! THIS FUNCTION COMPUTES THE VALUE OF THE DERIVATIVE OF THE 
    ! G-FUNCTION FOR A SLIT TRANSMISSION FUNCTION GIVEN BY A 
    ! PIECE-WISE CUBIC SPLINE, WHOSE PARAMETERS ARE 
    ! CONTAINED IN XNG,FNG AND GNG. 

    implicit none 

    integer, parameter :: rk = selected_real_kind(15) 

    integer :: ix, nv 
    real(kind=rk) :: dgdt 
    real(kind=rk) :: xng(nv) 
    real(kind=rk) :: fng(nv) 
    real(kind=rk) :: gng(nv) 
    real(kind=rk) :: x 

    ! ALLOWABLE ROUNDING ERROR ON POINTS AT EXTREAMS OF KNOT RANGE 
    ! IS 2**IEPS*MAX(!XNG(1)!,!XNG(NV)!). 
    integer, parameter :: ieps = -50 
    integer, save :: iflg = 0 
    integer :: j 

    real(kind=rk) :: tolerance 
    real(kind=rk) :: H 
    real(kind=rk) :: A, B 
    real(kind=rk) :: Q1, Q2 
    real(kind=rk) :: SS 
    real(kind=rk) :: Z 

    tolerance = 2.0_rk**IEPS * MAXVAL(ABS(XNG([1,NV]))) 

    ! TEST WETHER POINT IN RANGE. 
    if ((X < XNG(1) - tolerance) .or. (X > XNG(NV) + tolerance)) then 
    ! FUNCTION VALUE SET TO ZERO FOR POINTS OUTSIDE THE RANGE. 
    iflg = 0 
    DGDT = 0.0_rk 
    return 
    end if 

    ! ESTIMATE KNOT INTERVAL BY ASSUMING EQUALLY SPACED KNOTS. 
    J = abs(x-xng(1))/(xng(nv)-xng(1)) * (nv-1) + 1 

    ! ENSURE CASE X=XNG(NV) GIVES J=NV-1 
    J = MIN(J,NV-1) 

    ! INDICATE THAT KNOT INTERVAL INSIDE RANGE HAS BEEN USED. 
    IFLG = 1 

    ! SEARCH FOR KNOT INTERVAL CONTAINING X. 
    do 
    if ((x >= xng(j)) .or. (j==1)) EXIT 
    j = j-1 
    ! LOOP TILL INTERVAL FOUND. 
    end do 
    do 
    if ((x <= xng(j+1)) .or. (j==nv-1)) EXIT 
    j = j+1 
    ! LOOP TILL INTERVAL FOUND. 
    end do 

    ! CALCULATE SPLINE PARAMETERS FOR JTH INTERVAL. 
    H = XNG(J+1) - XNG(J) 
    Q1 = H*GNG(J) 
    Q2 = H*GNG(J+1) 
    SS = FNG(J+1) - FNG(J) 
    B = 3.0_rk*SS - 2.0_rk*Q1 - Q2 
    A = Q1 + Q2 - 2.0_rk*SS 

    ! CALCULATE SPLINE VALUE. 
    Z = (X-XNG(J))/H 
    DGDT = ((3.0_rk*A*Z + 2.0_rk*B)*Z + Q1)/H 

end function DGDT 

注意,我沒有以任何方式進行測試,也有可能是有一些錯誤的猜測,這樣的ieps應該是一個常數。另外,我不太確定iflg,並且ix參數似乎根本沒有被使用。所以我可能會出錯。對於公差,最好使用係數而不是差值,並且2.**-50不會在此處更改雙精度數字中最大值的值。另請注意,除了現在的自由格式外,我還使用了其他一些F90功能。

0

免責聲明:這裏只是提一個可能的解決方案,不推薦它...

多達所有其他的答案是有效的,並且支持一些Fortran IV標準代碼是一個噩夢,您可能仍希望/需要儘可能避免觸摸它。而且由於Fortran IV在循環方面有一些奇怪的行爲(循環總是循環至少一次IINM),所以使用「合適的」Fortran IV編譯器或許是是一個「好」的想法。

無論如何,所有這些都說英特爾編譯器例如本地支持Fortran IV和-f66編譯器開關,並且我確信其他編譯器也可以。這可能值得檢查。