본문 바로가기
프로그래밍/Fortran 77

[FORTRAN 기초] 알고리즘 3편: 소수 판별 및 약수 구하기 fortran code

by 오!쎈세! 2026. 6. 22.
소수(Prime Number)는 1보다 큰 자연수 중 1과 자기 자신만을 약수로 가지는 수이며, 약수(Divisor)는 어떤 수를 나누어떨어지게 하는 수임. 포트란 77의 정수 나눗셈 특성과 나머지 연산 함수(MOD)를 활용하여 두 가지 핵심 알고리즘을 구현해 본다.
🟪 1. 데이터 영역 및 변수 선언 (Specification)
나눗셈 연산 및 조건 판별에 사용할 변수들과 소수 여부를 기록할 플래그 변수를 선언함. 7번째 칸 규칙을 엄수해야 한다.
fortran code
12345678901234567890123456789012345678901234567890123456789012345678901234567890
C      ====== 1번째 칸에 'C'를 적으면 이 줄은 주석 공간이 됨 ======
       PROGRAM PRIME_DIVISOR
       IMPLICIT NONE
       
*      [소수 판별 변수] 대상 숫자(TARGET), 나눌 인덱스(DIV), 나머지 버퍼(REM)
       INTEGER PRMTGT, PRMDIV, PRMREM
*      [상태 플래그] 소수이면 1, 소수가 아님이 판명되면 0을 저장함
       INTEGER ISPRM

*      [약수 구하기 변수] 대상 숫자(TARGET)와 나눌 루프 인덱스(IDX)
       INTEGER DIVTGT, DIVIDX, DIVREM

🟩 2. 나머지 연산 함수를 통한 조건 분기 (Execution)
소수 판별은 2부터 대상 숫자 직전까지 나누어가며 나머지가 0이 되는지 감시하고, 약수 구하기는 1부터 대상 숫자까지 나누어 나머지가 0인 인덱스를 필터링하여 화면에 출력함.
fortran code
12345678901234567890123456789012345678901234567890123456789012345678901234567890
*      =============================================================
*      [알고리즘 A] 소수(Prime Number) 판별 루프
*      =============================================================
*      [초기화] 대상 숫자를 17로 세팅하고 초기 상태를 소수(1)로 설정함
       PRMTGT = 17
       PRMDIV = 2
       ISPRM = 1

*      대상 숫자 직전까지 나눗셈 회전을 반복 수행함
*      포트란 77의 DO 루프는 유연한 조건 탈출이 어려워 IF-GOTO 문장으로 제어함
40     IF (PRMDIV .LT. PRMTGT) THEN
*          [내장 함수 MOD] PRMTGT를 PRMDIV로 나눈 나머지를 반환함
           PRMREM = MOD(PRMTGT, PRMDIV)
           
*          나머지가 0이라는 것은 중간에 다른 수로 나누어떨어졌다는 뜻임
           IF (PRMREM .EQ. 0) THEN
               ISPRM = 0
           ENDIF
           
           PRMDIV = PRMDIV + 1
           GOTO 40
       ENDIF

*      [소수 결과 출력] 플래그 상태에 따라 최종 판정 결과를 인쇄함
       IF (ISPRM .EQ. 1) THEN
           WRITE(*, 900) PRMTGT
       ELSE
           WRITE(*, 910) PRMTGT
       ENDIF

*      =============================================================
*      [알고리즘 B] 약수(Divisor) 구하기 루프
*      =============================================================
       DIVTGT = 12
       WRITE(*, 920) DIVTGT

*      1부터 자기 자신(12)까지 자동으로 1씩 증가하는 DO 루프 개방
       DO 50 DIVIDX = 1, DIVTGT, 1
           DIVREM = MOD(DIVTGT, DIVIDX)
           
*          나머지가 0인 인덱스 번호만 약수로 판단하여 즉시 출력함
           IF (DIVREM .EQ. 0) THEN
               WRITE(*, 930) DIVIDX
           ENDIF
50     CONTINUE

       STOP

C      =================================================================
C      [FORMAT 정의 구역] 화면 표출 규격 선언 (1~5칸 레이블)
C      =================================================================
900    FORMAT(1X, I3, ' RESULT : PRIME NUMBER')
910    FORMAT(1X, I3, ' RESULT : NOT PRIME NUMBER')
920    FORMAT(1X, 'NUMBER ', I3, ' DIVISORS LIST :')
930    FORMAT(1X, I3)

       END

💡 [실무 팁] 포트란 77의 나머지 내장 함수 MOD 규칙과 IF-GOTO 제어
코볼의 DIVIDE REMAINDER 구문과 비교했을 때 포트란 77이 가지는 함수적 특성과 자격증 시험 단골 설계 기법을 정리함.
  • 간결한 내장 함수 MOD(A, B)의 편리함
    • 코볼에서는 나머지를 구하기 위해 몫 변수까지 억지로 선언하고 긴 명령문을 써야 했음.
    • 반면 포트란 77은 수식 연산 언어답게 MOD(대상수, 나눌수) 라는 직관적인 수학적 내장 함수를 제공하여 한 줄의 수식만으로 나머지를 버퍼에 담아내는 압도적인 가독성을 보여줌.
  • 포트란 77 루프 제어의 한계와 IF-GOTO 문단 설계
    • 포트란 77의 표준 DO 루프는 시작할 때 반복 횟수가 고정되므로, 중간에 조건이 만족했다고 해서 루프를 도중에 브레이크(Break)하여 강제 탈출하는 기능이 취약함.
    • 소수 판별 알고리즘 특성상 중간에 약수가 하나라도 발견되면 뒤의 루프는 돌 필요가 없기 때문에, 자격증 실기나 실무 배치에서는 DO 루프 대신 행 번호 레이블과 IF (조건) GOTO 레이블 구조를 결합하여 조건이 충족될 때까지 수동으로 루프를 회전시키는 최적화 기법이 널리 활용되었다.