2016-08-24 2 views
0

복잡한 정수를 계산할 필요가 없으며이 문제 때문에 Fortran 77로 작성된 관리자 프로그램에서 얻은 기존 프로그램을 가져 왔습니다. 그러나 몇 가지 문제가 있습니다. 주로 DATA Statement의 구문 오류와 관련이 있습니다.Fortran 90의 DATA 구문 구문 오류

FUNCTION CAUSSA(F,A,B,EPS) 
    IMPLICIT DOUBLE PRECISION (A-H,O-Z) 
    external f 
    REAL :: W(12),X(12) 
    DATA CONST /1.0D-12/ 
    DATA W & 
1 /0.10122 85362 9037 , 0.22238 10344 5337 , 0.31370 66458 7788 ,& 
2 0.36268 37833 7836 , 0.02715 24594 1175 , 0.06225 35239 3864 ,& 
3 0.09515 85116 8249 , 0.12462 89712 5553 , 0.14959 59888 1657 ,& 
4 0.16915 65193 9500 , 0.18260 34150 4492 , 0.18945 06104 5506/

    DATA X & 
1 /0.96028 98564 9753 , 0.79666 64774 1362 , 0.52553 24099 1632 ,& 
2 0.18343 46424 9565 , 0.98940 09349 9165 , 0.94457 50230 7323 ,& 
3 0.86563 12023 8783 , 0.75540 44083 5500 , 0.61787 62444 0264 ,& 
4 0.45801 67776 5722 , 0.28160 35507 7925 , 0.09501 25098 3763/
    DELTA=CONST*DABS(A-B) 
    CAUSSA=0.d0 
    AA=A 
5 Y=B-AA 
    IF(DABS(Y) .LE. DELTA) RETURN 
2 BB=AA+Y 
    C1=0.5*(AA+BB) 
    C2=C1-AA 
    S8=0.d0 
    S16=0.d0 
    DO 1 I=1,4 
    U=X(I)*C2 
1 S8=S8+W(I)*(F(C1+U)+F(C1-U)) 
    DO 3 I = 5,12 
    U=X(I)*C2 
3 S16=S16+W(I)*(F(C1+U)+F(C1-U)) 
    S8=S8*C2 
    S16=S16*C2 
    IF(DABS(S16-S8).GT.EPS*DABS(S16)) GO TO 4 
    CAUSSA= CAUSSA+S16 
    A=BB 
    GO TO 5 
4 Y=0.5*Y 
    IF(DABS(Y) .GT. DELTA) GO TO 2 
    write(2,7) 
    write(5,7) 
7 FORMAT(1X,35HCAUSSA...TOO HIGH ACCURACY REQUIRED) 
    CAUSSA=0.d0 
    RETURN 
END 

컴파일의 결과는 다음입니다 :

sample.f90:11: 

1 /0.10122 85362 9037 , 0.22238 10344 5337 , 0.31370 66458 7788 ,&  
1 
Error: Syntax error in DATA statement at (1) 
sample.f90:17: 

1 /0.96028 98564 9753 , 0.79666 64774 1362 , 0.52553 24099 1632 ,& 
1  
Error: Syntax error in DATA statement at (1) 

내가 gfortran 버전 4.4.7을 사용하여이 함수가 실제 적분을 계산에 코드의 일부이다. 배열을 다시 작성하려고했지만 결과는 항상 동일합니다. 이 기능이 통합에 적합하지 않지만 필자는 여전히이 기능이 필요합니다. 그것 없이는 오래된 프로그램이 무너지고 있습니다. 조언을 주시면 감사하겠습니다. 이 같은 자유 형식의 소스를 컴파일하려면

+0

컴파일 명령에'-ffixed-form '을 추가 할 수 있습니까 (또는 파일 확장자를'.f90'에서'.f'로 변경할 수 있습니까?). –

+0

누군가가 자유형 문장 진술 마커 (라인의 끝에 '&')를 추가하는 것으로 고정 폼 소스를 자유형 소스로 변환하려고 시도한 것처럼 보입니다.더 많은 것을하지 않고 (이 경우) 유효하지 않습니다. 고정형 소스로 돌아갈 수 없습니까, 아니면 완전히 자유형으로 변환해야합니까? – francescalus

+0

원본 코드입니까? 원본이 아닌 경우 게시 할 수 있습니까? – innoSPG

답변

3

, 거기에 당신은 아마

  1. 내가 라벨을 연속 선에서 불법 것을 확신 변경해야합니다 두 가지가있다, 그래서 그들은
  2. 을 제거해야
  3. gfortran은 부동 소수점 섹션 사이의 공백을 잘못 해석하므로 제거해야합니다. 이 같은

뭔가 :

DATA W & 
    /0.10122853629037 , 0.22238103445337 , 0.31370664587788 ,& 
    0.36268378337836 , 0.02715245941175 , 0.06225352393864 ,& 
    0.09515851168249 , 0.12462897125553 , 0.14959598881657 ,& 
    0.16915651939500 , 0.18260341504492 , 0.18945061045506/

아마 제대로 [브라우저에서 작성된 메모를하고 테스트하지] 컴파일해야한다.

+0

내 생각에 연속 줄의 한 자리 숫자 문 레이블은 OP의 원래 코드에서 실제로 연속 열 6에있는 열 6에있는 것입니다. SO의 코드 형식은 펀치 카드 레이아웃의 규칙을 따르지 않습니다. –

+0

@HighPerformanceMark : 그래 맞을 것 같습니다. 하지만 문제는 실제로 OP의 형식을 고정 형식에서 자유 형식으로 다시 형식을 바꾸는 것보다 실제로 그렇게 할 수 있다고 생각합니다. – talonmies

+1

고정 줄과 자유 줄 모두에 대해 연속 줄 작업을 수행하는 데 자주 사용되는 방법은 연속 줄에 & at 열 73을 추가하고 연속 줄에 & 6 줄 앞에 추가하는 것입니다. 고정 된 형태의 자유 형식 변환 프로그램은 인용 된 양식에 연속을 남겨서는 안됩니다. – tim18

0

원본 코드가 자유 형식 및 고정 원본 형식을 잘못 혼합했습니다. 자유 형식의 줄 연속은 다음 줄의 6 열에 문자를 입력하는 대신 후행 앰퍼샌드 문자 &을 사용하여 수행합니다. 고정 소스 형식에서 처음 6 개 열은 명령문 레이블 용으로 예약되며 열 1은 주석 행을 나타내는데도 사용됩니다. 현대 코드에서 구조화 된 제어 문 (예 : select case 또는 if-then-else) 문 레이블을 사용하는 것은 드문 경우입니다. 따라서 처음 다섯 열은 거의 사용되지 않기 때문에 낭비됩니다.

다음
program main 

    use ISO_Fortran_env, only: & 
     compiler_version, & 
     compiler_options 

    ! Explicit typing only 
    implicit none 

    ! Variable declarations 
    double precision :: a, b, eps, x 

    a = 1.0d0 
    b = 2.0d0 
    eps = epsilon(a) 
    x = caussa(my_func, a, b, eps) 

    print '(/4a/)', & 
    ' This file was compiled using ', compiler_version(), & 
    ' using the options ', compiler_options() 

contains 

    function my_func(arg) result (return_value) 
     ! Dummy arguments 
     double precision, intent (in) :: arg 
     double precision    :: return_value 

     return_value = arg * 42.0d0 

    end function my_func 

    function caussa(f,a,b,eps) 

     use ISO_Fortran_env, only: & 
      stderr => ERROR_UNIT 

     implicit double precision (a-h,o-z) 
     external f 
     integer :: i 
     real :: w(12),x(12) 
     data const /1.0d-12/ 
     data w & 
     /0.10122853629037, 0.22238103445337, 0.31370664587788 ,& 
     0.36268378337836, 0.02715245941175, 0.06225352393864 , & 
     0.09515851168249, 0.12462897125553, 0.14959598881657 , & 
     0.16915651939500, 0.18260341504492, 0.18945061045506/

     data x & 
     /0.96028985649753, 0.79666647741362, 0.52553240991632, & 
     0.18343464249565, 0.98940093499165, 0.94457502307323, & 
     0.86563120238783, 0.75540440835500, 0.61787624440264, & 
     0.45801677765722, 0.28160355077925, 0.09501250983763/

    delta=const*dabs(a-b) 
    caussa=0.d0 
    aa=a 
5 y=b-aa 
    if (dabs(y) <= delta) return 
2 bb=aa+y 
    c1=0.5*(aa+bb) 
    c2=c1-aa 
    s8=0.d0 
    s16=0.d0 
    do 1 i=1,4 
     u=x(i)*c2 
1  s8=s8+w(i)*(f(c1+u)+f(c1-u)) 
     do 3 i = 5,12 
      u=x(i)*c2 
3   s16=s16+w(i)*(f(c1+u)+f(c1-u)) 
      s8=s8*c2 
      s16=s16*c2 
      if (dabs(s16-s8)>eps*dabs(s16)) go to 4 
      caussa = caussa+s16 
      a = bb 
      go to 5 
4   y = 0.5*y 
      if (dabs(y) > delta) go to 2 
      write(2,7) 
      write(stderr,7) 
      ! 
      ! 7 format(1x,35hcaussa...too high accuracy required) 
      ! Hollerith format specifier is a Fortran 95 deleted feature 
      ! 
7    format(1x, 'caussa...too high accuracy required') 
      caussa=0.d0 

    end function caussa 

end program main 

는 고정 된 형태를 버전

 PROGRAM MAIN 

     USE ISO_FORTRAN_ENV, ONLY: 
    1 COMPILER_VERSION, 
    2 COMPILER_OPTIONS 

C EXPLICIT TYPING ONLY 
     IMPLICIT NONE 

C VARIABLE DECLARATIONS 
     DOUBLE PRECISION :: A, B, EPS, X 

     A = 1.0D0 
     B = 2.0D0 
     EPS = EPSILON(A) 
     X = CAUSSA(MY_FUNC, A, B, EPS) 

     PRINT '(/4A/)', 
    1 ' THIS FILE WAS COMPILED USING ', COMPILER_VERSION(), 
    2 ' USING THE OPTIONS ', COMPILER_OPTIONS() 

     CONTAINS 

     FUNCTION MY_FUNC(ARG) RESULT (RETURN_VALUE) 
C DUMMY ARGUMENTS 
     DOUBLE PRECISION, INTENT (IN) :: ARG 
     DOUBLE PRECISION    :: RETURN_VALUE 

     RETURN_VALUE = ARG * 42.0D0 

     END FUNCTION MY_FUNC 

     FUNCTION CAUSSA(F,A,B,EPS) 

     USE ISO_FORTRAN_ENV, ONLY: 
    1 STDERR => ERROR_UNIT 
     IMPLICIT DOUBLE PRECISION (A-H,O-Z) 
     EXTERNAL F 
     INTEGER I 
     REAL :: W(12), X(12) 
     DATA CONST /1.0D-12/ 
     DATA W 
    1 /0.10122 85362 9037, 0.22238 10344 5337, 0.31370 66458 7788, 
    2 0.36268 37833 7836, 0.02715 24594 1175, 0.06225 35239 3864, 
    3 0.09515 85116 8249, 0.12462 89712 5553, 0.14959 59888 1657, 
    4 0.16915 65193 9500, 0.18260 34150 4492, 0.18945 06104 5506/
     DATA X 
    1 /0.96028 98564 9753, 0.79666 64774 1362, 0.52553 24099 1632, 
    2 0.18343 46424 9565, 0.98940 09349 9165, 0.94457 50230 7323, 
    3 0.86563 12023 8783, 0.75540 44083 5500, 0.61787 62444 0264, 
    4 0.45801 67776 5722, 0.28160 35507 7925, 0.09501 25098 3763/

     DELTA=CONST*DABS(A-B) 
     CAUSSA=0.D0 
     AA=A 
    5 Y=B-AA 
     IF(DABS(Y) .LE. DELTA) RETURN 
    2 BB=AA+Y 
     C1=0.5*(AA+BB) 
     C2=C1-AA 
     S8=0.D0 
     S16=0.D0 
     DO 1 I=1,4 
     U=X(I)*C2 
    1 S8=S8+W(I)*(F(C1+U)+F(C1-U)) 
     DO 3 I = 5,12 
     U=X(I)*C2 
    3 S16=S16+W(I)*(F(C1+U)+F(C1-U)) 
     S8=S8*C2 
     S16=S16*C2 
     IF(DABS(S16-S8).GT.EPS*DABS(S16)) GO TO 4 
     CAUSSA= CAUSSA+S16 
     A=BB 
     GO TO 5 
4 Y=0.5*Y 
     IF(DABS(Y) .GT. DELTA) GO TO 2 
     WRITE(2,7) 
     WRITE(STDERR,7) 
C 
C 7 FORMAT(1X,35HCAUSSA...TOO HIGH ACCURACY REQUIRED) 
C HOLLERITH FORMAT SPECIFIER IS A FORTRAN 95 DELETED FEATURE 
C 
    7 FORMAT(1X, 'CAUSSA...TOO HIGH ACCURACY REQUIRED') 
     CAUSSA=0.D0 
     RETURN 
     END FUNCTION CAUSSA 
     END PROGRAM MAIN 

자유 형식으로, "중요한 공백의 개념 : 여기

같은 자유 형식의 코드와 고정 소스 형식입니다 "도입되었습니다. 고정 소스에서 대부분의 컨텍스트에서는 공백이 중요하지 않았습니다. 여기에 이제 공백없이 동등한 문 다음에 중요한 공백을 고려하는 것을 보여주는 고정 소스 문장의 예입니다 : 우리가

data w & 
/0.10122853629037, blah blah 

DATA W 
1 /0.10122 85362 9037, blah blah 

을 재 작성하는 방법

DO N = 1, MAX ITER S 

DO N = 1, MAXITERS 

공지 사항