반응형

     정보

    • 업무명     : 포트란을 활용한 기초 1 : 개요, 포트란 기초, 기본 자료형, 형변환

    • 작성자     : 이상호

    • 작성일     : 2020-11-09

    • 설   명      :

    • 수정이력 :

     

     내용

    [개요]

    • 안녕하세요? 웹 개발 및 연구 개발을 담당하고 있는 해솔입니다.

    • Fortran (포트란)은 수식 (Formular) 변환기 (Translator)의 약자로 과학 계산용으로 주고 사용되는 언어입니다.

    • 복잡한 계산 수행 성능이 뛰어나 공학과 자연과학 등 특정분야에 주로 사용되며 기상 데이터 처리를 위해 널리 사용되고 있습니다.

    • 오늘 포스팅은 포트란을 활용한 기초 1을 소개합니다.

     

     

    [특징]

    • 기상 데이터 처리를 위해서 포트란 (Fortran)기술이 요구되며 이 프로그램은 이러한 목적을 달성하기 위한 기술서

     

    [기능]

    • 개 요

    • 포트란 기초

    • 기본자료형, 형변환

     

    [활용 자료]

    • 없음

     

    [자료 처리 방안 및 활용 분석 기법]

    • 없음

     

    [사용법]

    • 없음

     

    [사용 OS]

    • Linux (CentOS v7.8)

     

    [사용 언어]

    • gfortran v4.8.5

     

     세부 내용

    개요
    • 포트란 (Fortran) 은 FORmula TRANslation 의 약자로, 수학/과학 계산을 위한 프로그래밍 언어입니다.

    • C가 더 범용적이나 포트란은 빠른 계산속도를 자랑합니다.

    • 포트란을 쓰는 이유는 수식을 간략히 표현 할 수 있어 복잡한 계산 프로그램을 빠르게 만들 수 있으며 이를 바탕으로 오래전부터 만들어진 수많은 공개된 수학/과학, 병렬컴퓨팅 라이브러리가 존재하기 때문입니다.

    • 방대한 양의 코드가 이미 포트란 77 로 만들어져 있어 포트란 77 문법을 다뤄야 맞겠지만 포트란 77 특유의 제약조건들이 90/95에서 제거되면서 코드를 작성하기 더 용이해 졌습니다.

    • 물론 77 코드는 90/95 에서 대부분 호환이 됩니다. 즉, 90/95 에서는 77의 장점도 쓸 수 있고, 90/95 의 장점도 쓸 수 있습니다.

    • 확장자는 77 이 .for 이고, fixed 포맷이며, 90 은 .f90 이고 free 포맷입니다.

    • 즉 코드를 작성할 때 형식을 지켜야 되느냐 지키지 않아도 되냐의 차이 입니다.

    • 다른 언어와 마찬가지로, 컴파일과 링크는 컴퓨터 아키텍처 및 운영체제에 종속적입니다. 

    • 따라서 운영체제 등을 고려하여 컴파일러를 결정해야 합니다.

     

    포트란 기초
    • 주석

      • 포트란 77 까지는 주석문의 시작을 레이블링 하는 컬럼에 C (comment) 로 나타냅니다.

      • 90/95 는 프리포맷으로서 아무 위치에서나 ! 를 사용합니다.

      • ! 주석문은 해당 줄의 끝까지 주석처리가 됩니다.

      • 컴파일러는 주석문을 무시합니다.

    INTEGER :: variable names
    REAL :: real_variables
    CHARACTER [ ( len = length ) ] :: variable names
    ! CHARACTER [ ( length ) ] :: variable names

     

    • 코딩문자

      • 포트란 코딩에서 사용되는 문자들은 다음과 같은 것을 쓸 수 있습니다. 

    알파벳 26 개 ( 혹은 42개 )  
    주의. case insensitive : 대소문자 구별 안 함 , 
    숫자 9 개 
    언더바 _ 
    !  
    사칙연산 + - * / 
    거듭제곱 ** 
    대입연산자 = 
    각종 기호들 ( ) < > : ; . , ' " ! ? % & $ 
    빈칸

     

    • 문장 (statement)

      • 기본적으로 한 문장은 한 줄에서 작성하고, 너무 길거나 가독성의 이유로, 여러줄로 쓸때는 & 를 사용합니다.

    a = b + c ! 1번
    a = b &
    + c ! 2번
    ! 1번처럼 작성하나 2번처럼 작성하나 같다.

     

    • 레이블링 (labeling)

      • 문장에 고유번호를 부여해서, 레이블링 할 수 있으며, 1 부터 99999 까지의 숫자를 사용한다.

      • 보통 GO TO 문에 쓰이며 다음 문장이 아닌 해당 숫자로 이동해라는 뜻 입니다.

    GO TO 99 
    X = 67.8 
    99 Y = -1

     

    • 기본구조

      • 프로그램의 큰 틀은 크게 3 가지 영역으로 구성됩니다.

      • 선언영역 (Declaration section) : 프로그램명, 변수 등을 선언

      • 실행영역 (Execution Section) : 각종 계산 및 명령을 수행

      • 종료영역 (Termination Section) : 프로그램을 종료

      • 서브루틴이나 모듈 등도 위와 같은 구조를 갖습니다. 이에 대해서는 나중에 자세히 살펴보도록 하겠습니다.

         

    • 프로그램 명 선언

      • PROGRAM program_name

        • PROGRAM 문은 비실행문으로, 코드 첫 줄에 오며, 프로그램의 이름을 컴파일러에게 전달합니다.

        • 포트란은 대소문자 구별이 없기 때문에 program 이라고 쓸 수 있지만, 보통 키워드를 대문자로 쓰는 관습이 있습니다.

        • 프로그램 명에는 알파뉴머릭 (alphanumeric) 과 언더바(_) 를 쓸 수 있습니다.

     

    • 변수 선언

      • 정수변수의 선언은 INTEGER, 실수형 변수의 선언은 REAL 을 사용하며 문자변수는 CHARACTER 를 사용합니다.

      • 기본적인 구문은 다음과 같습니다.

    INTEGER :: variable names
    REAL :: real_variables
    CHARACTER [ ( len = length ) ] :: variable names
    CHARACTER [ ( length ) ] :: variable names
    ! length 부분에 숫자를 써넣으면, 문자열 데이터가 된다. ( len = ) 부분을 생략하면, 자동으로
    길이가 1 로 설정되고, 단일문자 변수가 된다. ( len = 숫자 ) 대신 그냥 ( 숫자 ) 로 써도 된다.

     

    • 실행영역

      • 기본적인 4칙 연산은 C언어와 같고, C언어에는 거듭제곱이 없는데, 포트란의 경우 계산 언어 답게 거듭제곱이 있습니다.

      • 포트란에서는 ** 를 사용합니다.

      • 기본적인 입출력함수로 출력은 WRITE(or PRINT) , 입력은 READ 문을 사용합니다. 

      • WRITE 와 READ 의 구문에 대해서는 따로 살펴보기로 하겠습니다.

     

    • 종료영역

      • 종료영역에서는 STOP 문과 END PROGRAM 문을 사용합니다.

      • STOP 문은 프로그램의 실행을 정지시키라는 명령입니다.

      • END PROGRAM 은 컴파일러에게 더 이상 컴파일 할 문장이 없음을 알려주는 문장입니다.

      • 그런데 END PROGRAM을 만나면, 어차피 컴파일러가 자동으로 STOP 명령을 내리기 때문에 STOP 과 END PROGRAM 문이 연달아 붙어있는 경우에는 둘 중 하나만 써도 상관 없습니다.

      • END PROGRAM 뒤에, 종료시킬 프로그램을 명시적으로 나타내 줄 수도 있습니다.

      • END PROGRAM [ program name ]

    • 예제코드

      • 간단한 계산 예제를 통해, 기본적인 구조를 살펴보겠습니다.

      • 다음의 예제코드는 두 실수를 입력 받아서, 그 첫 번째 수에 두 번째 수를 거듭제곱한 값을 출력하는 프로그램 입니다.

    PROGRAM power
    READ (*,*) x,y
    z = x ** y
    WRITE (*,*) z
    END PROGRAM
    ! 똑같은 내용을 c로 작성해보면 포트란이 상당히 계산에 특화되었음을 느낄 수 있다.

     

    결과
    17, 1.5
    70.09280

     

    기본자료형, 형변환
    • 정수형 데이터 타입

      • 정수형 상수는 점을 찍을 경우, 실수로 인식합니다.

      • 예를 들어 100 은 정수지만, 100. 과 같이 점을 찍으면 실수가 됩니다.

      • 정수형 데이터가 메모리에 저장될 때, 기본 크기는 해당 컴퓨터의 word 크기에 의존합니다.

      • 가령 4바이트 워드 컴퓨터 (32비트 컴퓨터) 의 경우, 정수형 데이터는 기본 4바이트가 됩니다.

      • 몇 바이트 형 정수형 데이터 타입을 쓸 것인가는 KIND 를 사용해서 기술할 수 있습니다.

    INTEGER ( KIND = kindnumber ) :: variables
    INTEGER ( kindnumber ) :: variables

     

    • 사용하고자 하는 숫자가 몇 바이트 정수형을 요구하는지를 체크하는 함수로 SELECTED_INT_KIND() 함수가 있습니다.

    SELECTED_INT_KIND( range )

     

    • 가령 SELECTED_INT_KIND(x) 는 ( -10^x , +10^x ) 을 표현하는데 요구되는 최소 kind_number 를 반환합니다.

    • 정수형 상수의 경우에도, 메모리크기를 지정할 수 있습니다. 상수 뒤에 언더바 _ 와 kind 를 기술해주는것입니다.

    • 예를 들어, 32 라고 하면, 이것은 디폴트 kind 를 갖게 됩니다.

    • 그러나 32_8 이라고 하면, 8바이트(64비트) 정수형 자료가 됩니다.

    • 10의 지수형 범위가 아니라, 그냥 해당 상수나, 해당 변수에 대해서 직접 KIND 를 주는 내장함수로 KIND() 가 있습니다.(이것은 자신의 디폴트를 확인하는데도 유용)

    • 참고로 KIND() 함수는, 정수형 데이터에 국한되는 것이 아니라, 여러 자료형에 쓸 수 있는 함수입니다.

    KIND( data )
    KIND( 3 ) , KIND( 3_8 ) ! 전자는 디폴트를 줄 것이고, 후자는 8 을 준다.
    KIND (i) ! 변수 i 의 KIND 를 보여준다.

     

    • 실수형 데이터 타입

      • 실수형 상수에서 지수형 표기법은 E 와 D 를 사용하는데, E는 싱글 프리시전(single precision) , D는더블 프리시전( double precision) 입니다.

      • C언어 에서 싱글 프리시전으로 float , 더블 프리시전으로 double 을 사용하는 것과 비슷하게, 포트란에서는 KIND 를 이용해, 실수 자료형의 정밀도를 선택할 수 있습니다.

      • 가장 흔한 경우는, KIND = 4 가 4바이트 실수(32비트)형 , KIND =8 이 8바이트 실수(64비트)형이 있습니다.

    REAL(KIND= kind number) :: variables
    REAL(kind number) :: variables
    ! () 의 kind 는 옵션으로 생략하면 디폴트가 적용됩니다.

     

    • 정수형에 SELECTED_INT_KIND() 함수가 있었던 것처럼, 실수형에는 SELECTED_REAL_KIND() 함수가 있습니다.

    SELECTED_REAL_KIND( p= precision, r= range )

     

    • 여기서 precision 은 유효숫자의 수이고, range 는 10의 지수범위입니다.

    • 리턴값은 kind number 이고, precision 에서 오버되면 -1 , range 에서 오버되면 -2 , 둘 다 오버되면 -3 을 리턴 합니다.

    • REAL 데이터의 precision 과 range 를 알려주는 내장함수로 다음의 두 함수가 있습니다.

    • 두 함수 모두 인자로 실수데이터나 복소수데이터를 받습니다.

    • precision() 은 decimal precision 을 리턴하고, range() 는 decimal exponent range 를 반환합니다.

    PRECISION( real_or_complex )
    RANGE( real_or_complex )

     

    • 복소수형 데이터 타입

      • 아무래도 계산에 특화된 프로그래밍 언어이다 보니, 복소수형 타입이 사용자정의형으로 만들어서 사용하는 것이 아니라 기본형 타입으로 지정 되어 있습니다.

      • 복소수상수는 (a,b) 와 같이 사용되고, 이것은 a + i b 를 나타냅니다. 

      • 여기서 a 와 b는 자동으로 실수타입으로 가정됩니다.

      • 복소수변수의 선언은 다음과 같습니다.

    COMPLEX (KIND= kind number ) :: variables
    COMPLEX (kind number ) :: variables
    ! () 의 kind 는 옵션으로 생략하면 디폴트가 적용됩니다.

     

    • KIND 는 실수형과 같지만, 실수타입 두 개를 하나로 사용합니다.

    • 복소수의 기본적인 사칙연산은 우리가 아는 그대로 적용됩니다.

    • 복소수 타입은 실수 타입을 포함하는 데이터타입으로, 상당히 유연하여, 실수와 혼합하여 연산이 가능합니다.

    • 예를 들어, 3 + (2,4) = (5,4) 로 연산됩니다.

    • 즉 복소수의 입출력에 있어서도, 괄호 없이 실수만 입력 할 경우 그것을 실수부로 받아들이고, 허수부는0 이 되도록 합니다.

    • 포트란의 복소수 타입은 사칙연산 외에도 다른 연산들을 지원하는데, 특히 염두에 둘 것은 거듭제곱 연산자 ** 입니다.

    • 가령 (3,2) ** 0.5 이나 (3,2) ** (4,-1) 과 같은 연산이 가능합니다.

    PROGRAM complex
      COMPLEX :: z1, z2
      z1 = (3,4) + (2,7)
      z2 = (3,4) + (2,7)
      WRITE (*,*) z1,z2
    END PROGRAM

     

    결과
    (5.000000,11.00000) (-22.00000,29.00000)

     

    • 논리형 데이터 타입

      • 논리상수는 .TRUE. 와 .FALSE. 두 가지인데, 주의할 점은, 양쪽에 점을 찍어줘야 한다는 점입니다. 

      • 그렇지 않고 그냥 TRUE 와 FALSE 로 넣게 되면, 변수명이 되기 때문입니다.

      • .TRUE. 와 .FALSE. 를 그냥 WRITE로 찍으면, .TRUE. 는 T 로 , .FALSE. 는 F 로 출력 됩니다.

      • 논리형 타입의 입력 시 에도 .TRUE. 나 .FALSE 대신 T 와 F 로 간단히 입력할 수 있습니다.

      • 논리형 변수 선언은 다음과 같습니다.

    LOGICAL :: variables

     

    • 대소비교 연산이나 조건분기 등의 조건문에 대한 평가는 논리값으로 이루어집니다.

    • 논리연산자에 대해서는 뒤에서 자세히 다루기로 하겠습니다.

    • 문자형 데이터 타입

      • 포트란의 문자 및 문자열 상수는 작은따옴표 ( single quote ) 나 큰따옴표 ( double quote ) 를 사용합니다.

      • C언어 에서는 문자에 작은따옴표, 문자열에 큰따옴표를 쓰나 포트란에서는 짝만 맞게 써주면 구분하지 않습니다.

      • 이것이 신기한 유용성을 가져다 줍니다.

      • 가령 Man's best friend 라는 문자열을 묶어서 문자열 상수로 만들 때, 작은따옴표로 묶는 방법과 큰따옴표로 묶는 방법을 살펴보면, 다음과 같습니다.

      • 작은따옴표 : 'Man''s best friend' ` 를 찍기 위해 작은따옴표 를 연달아 두 번 찍어준다.

      • 큰따옴표 : "Man's best friend" 큰따옴표로 묶을 때는 `가 문제되지 않는다.

      • 큰따옴표 자체가 들어있는 문장을 찍을 때는 그 문장자체를 작은따옴표로 감싸고, 혹시 그 안에 `가 있으면 작은따옴표를 연달아 써서 '를 찍도록 합니다.

      • 예를 들어 "This is me." 를 나타내는 문자열상수는 ' "This is me." ' 으로 쓸 수 있습니다.

      • 문자/문자열 변수의 선언은 다음과 같습니다.

    CHARACTER :: single_character_variables
    CHARACTER ( len = length ) :: string_variables
    CHARACTER ( length ) :: string_variables
    ! 길이를 넣어주면 문자열, 길이가 없으면 문자형이 선언 됨.

     

    PROGRAM str
    	WRITE (*,*) '"This is me."'
    END PROGRAM

     

    • 형변환 함수

      • C언어에서 괄호를 이용하여 형변환 함수를 사용하는 것과 유사하게 포트란에서의 자료형 변환 함수는 다음과 같이 제공됩니다.

    INT(x) ! 실수자료에서 소수점 이하 버리고 정수부분만 리턴 한다.
    NINT(x) ! 소수부분을 반올림한 정수를 리턴 한다. 앞의 N 은 nearest 를 의미한다.
    REAL(i) ! 정수값을 실수형으로 변환한다.

     

     참고 문헌

     문의사항

    [기상학/프로그래밍 언어]

    • sangho.lee.1990@gmail.com

    [해양학/천문학/빅데이터]

    • saimang0804@gmail.com
    반응형
    • 네이버 블러그 공유하기
    • 네이버 밴드에 공유하기
    • 페이스북 공유하기
    • 카카오스토리 공유하기