2014-11-30 1 views
1

다음과 같이 각도를 변환하는 3 가지 변환 함수가 있습니다.다른 유형을 허용하는 Fortran 함수

함수 반환 값은 입력 값과 같습니다. 즉, 입력 각도가 프로그래머가 출력 을 원하는 유형이거나, 예를 들어 al = convert(Real(30),"deg_to_rad")을 사용하여 필요한 출력 유형으로 변환하려는 유형이어야합니다.

프로그래머가 al = convert(30,"deg_to_rad")을 수행 할 수 있기를 바랍니다. 출력 형식을 으로 정의하려면 내재적 인 transfer 전략을 사용하는 것이 좋습니다.

Real :: al, mold  
al = convert(30,"deg_to_rad", mold) 
al = convert(30.0,"deg_to_rad", mold) 

Double Precision :: al, mold  
al = convert(30,"deg_to_rad", mold) 
al = convert(30.0,"deg_to_rad", mold) 

내가 가진 기능이 있습니다. 좋은 계획을 구현하고 진행하는 방법에 대해 몇 가지 아이디어를 가지고있는 것이 좋을까요 .

Interface convert 
    Module Procedure convert 
    Module Procedure convert_real 
    Module Procedure convert_dble 
    Module Procedure convert_real128 
End Interface convert 

Contains 

Function convert_real & 
    (    & 
    qa, label  & 
)    & 
Result (qb) 

Real, Intent (in) :: qa 
Character (len=*), Intent (in) :: label 

Real :: qb 

If (label .contains. "angle:") Then 

Block 

    Real :: pi, deg_to_rad 

    pi = 22.0/7.0 
    deg_to_rad = pi/180.0 

    Select Case (Trim (label)) 

    Case ("angle: deg_to_rad") 
     qb = deg_to_rad * qa 

    End Select 

End Block 

End If 

End Function convert_real 


Function convert_dble & 
    (     & 
    qa, label   & 
)     & 
Result (qb) 

Double Precision, Intent (in) :: qa 
Character (len=*), Intent (in) :: label 

Double Precision :: qb 


If (label .contains. "angle:") Then 

Block 

    Double Precision :: pi, deg_to_rad 

    pi = Dble(22)/Dble(7) 
    deg_to_rad = pi/Dble(180) 

    Select Case (Trim (label)) 

    Case ("angle: deg_to_rad") 
     qb = deg_to_rad * qa 

    End Select 

End Block 

End If 

End Function convert_dble 


Function convert_real128 & 
    (      & 
    qa, label    & 
)      & 
Result (qb) 

Real (Real128), Intent (in) :: qa 
Character (len=*), Intent (in) :: label 

Real (Real128) :: qb 

If (label .contains. "angle:") Then 

Block 

    Real (Real128) :: pi, deg_to_rad 
    pi = Real(22,Real128)/Real(7,Real128) 
    deg_to_rad = pi/Real(180,Real128) 

    Select Case (Trim (label)) 

    Case ("angle: deg_to_rad") 
     qb = deg_to_rad * qa 

    End Select 

End Block 

End If 

End Function convert_real128 

I는 입력과 출력이 서로 다른 유형의 때 서브 루틴을 사용하는 것을 시도하고있다. 내가

Subroutine convertor & 
    (     & 
    qa, label, qb  & 
) 

Class (*), Intent (in) :: qa 
Character (len=*), Intent (in) :: label 

Class (*), Intent (out) :: qb 

Select Type (qb) 

Type Is (Real) 
    qb = convert (Real(qa),label) 

Type Is (Double Precision) 
    qb = convert (Dble(qa),label) 

Type Is (Real (Real128)) 
    qb = convert (Real(qa,Real128),label) 

End Select 

End Subroutine convertor 

아래의 오류가 발생하지만 여기에 내가 당신이 뭘 하려는지 이해한다면,이 불필요하게 복잡하게 보인다 오류

gfortran -o build/lib/foul.o -c -ffree-form -g -J./build/lib lib/foul.f 
gfortran -o build/lib/meidum.o -c -ffree-form -g -J./build/lib lib/meidum.f 
lib/meidum.f:890.26: 

    qb = convert (Real(qa),label) 
         1 
Error: 'a' argument of 'real' intrinsic at (1) must be a numeric type 
lib/meidum.f:893.26: 

    qb = convert (Dble(qa),label) 
         1 
Error: 'a' argument of 'dble' intrinsic at (1) must be a numeric type 
lib/meidum.f:896.26: 

    qb = convert (Real(qa,Real128),label) 
         1 
Error: 'a' argument of 'real' intrinsic at (1) must be a numeric type 
+0

문제점 중 하나는 함수의 결과 유형에 Class (*)를 사용할 수 없다는 것입니다. 따라서 코드는 곰팡이를 사용할 수 없습니다. – Zeus

답변

3

에게 있습니다. transfer을 모델로 사용하는 대신 sin과 같은 산술 내장 함수를 사용하십시오. Fortran (FORTRAN 77부터)은 인수에 따라 다양한 사인 함수 (실수, 배정도, 4 배 정밀도)를 자동으로 구별 할 수 있습니다. 각 기능을 작성한 후 interface으로 표기하여 module procedure으로 지정하여 일반화하십시오. 예 : Overloading functions with Fortran

편집 : 그것은 당신이 원하는에 따라 달라집니다 : 나에게

result = convert (input) 

, 인수 input의 종류에 의해 제어 함수 반환 유형을 가지고 가장 자연스러운 것 같다. 이것이 제가 설명하고 예에서 보여주는 것입니다. result 유형이 다른 경우 포트란이 할당을 변환합니다 ... 컴파일러 옵션을 선택하여 경고를 생성하면 단점이 있습니다. 따라서 result 유형을 convert으로 계산 된 유형을 제어하려면이 기술을 수정해야합니다. 함수 반환은이 오버로드를 구분하지 않기 때문에 함수를 사용할 수 없습니다. 이 인터페이스/모듈 절차에서 잘 작동합니다

call convert (input, result) 

: 다음 구분됩니다 인수가되는 대신에 서브 루틴을 사용합니다. 왜 이것이 효과가 없을지 모르겠다. 할당 문/함수 표기법보다 사용법이 조금 덜 우아 할 수 있습니다.

+0

그게 내가하려고 노력한 것입니다. 나는 실수, 배정도 및 실수 (real128)에 대해 다른 기능을 가지고있다. 입력 유형은 함수가 작동하기위한 출력과 동일해야합니다. 아마 정수를 취할 수 있지만 실제를 출력 할 수있는 다른 함수가 필요할 것입니다. – Zeus

+0

프로그래머가 변수를 입력하지 않으면 함수가 반환 형식을 알 수있는 방법을 찾을 수 없습니다. – Zeus

+1

나는 @M.S에 동의한다.B. 위에 지적 된 문제의 예를 따르십시오. 'sin'과 같은 내장 함수처럼 함수는 인수가 전달 된 것과 같은 종류를 반환해야합니다. 결과를 다른 종류 (또는 유형)로 캐스팅하고 싶다면'sin '과 마찬가지로 명시 적으로 처리하십시오.'TRANSFER'를 사용하는 경우, 처음 32 비트 또는 마지막 64 비트 실수의 32 비트를 32 비트 실수로 변환합니까? 전송은 타입 캐스트하지 않으며, 잠재적으로 위험한 코드를 프로그래머가 메모리에있는 비트를 잘못 해석하도록 허용합니다. –

관련 문제