정보
-
업무명 : 포트란을 활용한 기초 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) ! 정수값을 실수형으로 변환한다.
참고 문헌
[논문]
- 없음
[보고서]
- 없음
[URL]
- Fortran을 활용한 분석, 날씨마루 (기상기후 빅데이터 분석 플랫폼), bd.kma.go.kr/kma2020/dta/edu/KBP57200_Fortran.do?pageNum=5&menuCd=F040304000.
문의사항
[기상학/프로그래밍 언어]
- sangho.lee.1990@gmail.com
[해양학/천문학/빅데이터]
- saimang0804@gmail.com
'프로그래밍 언어 > Fortran' 카테고리의 다른 글
[Fortran] 포트란을 활용한 에러 : 개요, NaN and Inf3, 예외 처리 (Exception), 에러 종류와 예시 (0) | 2020.11.11 |
---|---|
[Fortran] 포트란을 활용한 기초 2 : 상수,키워드, 기본 제어입출력, 연산자 (논리, 관계, IF, CASE, DO, CYCLE) (0) | 2020.11.10 |
[Fortran] 포트란 Random 함수를 이용한 정규 분포 가시화 (0) | 2020.01.29 |
[Fortran] 포트란 유닉스 시간 (Unix Time)을 날짜로 변환 (0) | 2020.01.28 |
[Fortran] 포트란 텍스트 및 CSV 파일에서 날짜 및 시간 읽기 (0) | 2020.01.25 |
최근댓글