#runtime #fortran
#время выполнения #fortran
Вопрос:
Я на начальном уровне в FORTRAN. Недавно я попытался разработать простую программу для вычисления перестановок и комбинаций. У него будет «меню», в котором пользователь может выбрать вариант продолжения…
!/*-------MAIN PROGRAM STARTS-------*/
!PURPOSE: TO CALCULATE COMBINATIONS AND PERMUTATIONS
PROGRAM COMBINATION_PERMUTATION
IMPLICIT NONE
!DECLARATION OF VARIABLES
REAL N, K, FACT, COMBINATION, PERMUTATION
INTEGER CHOICE
!CHOICE MENU
CALL MENU
!USER INPUT OF CHOICE
READ(*,*) CHOICE
!EXECUTION OF CODE BASED ON USER'S CHOICE
SELECT CASE(CHOICE)
CASE(1)
!CALLS SUBROUTINE FOR COMBINATION
CALL COMBINATION_CALC (N, K, FACT, COMBINATION)
CASE(2)
!CALLS SUBROUTINE FOR PERMUTATION
CALL PERMUTATION_CALC (N, K, FACT, PERMUTATION)
CASE(3)
!EXITS THE PROGRAM
STOP
CASE DEFAULT
!INVALID CHOICE LEADS TO MENU BACK
WRITE(*,*) 'INVALID CHOICE! PLEASE CHOOSE AN OPTION TO CONTINUE'
CALL MENU
END SELECT
END PROGRAM COMBINATION_PERMUTATION
!/*-------MAIN PROGRAM ENDS-------*/
!/*-------SUB PROGRAMS START-------*/
!FUNCTION FOR FACTORIAL
FUNCTION FACT(N)
IMPLICIT NONE
REAL FACT, N
INTEGER P, I
P=1
DO I=1, N
P=P*I
END DO
FACT=P
RETURN
END FUNCTION
!SUBROUTINE FOR MENU
SUBROUTINE MENU
IMPLICIT NONE
WRITE(*,*) ' CHOOSE AN OPTION TO CONTINUE.. '
WRITE(*,*) ' 1. COMBINATION '
WRITE(*,*) ' 2. PERMUTATION '
WRITE(*,*) ' 3. EXIT PROGRAM '
RETURN
END SUBROUTINE MENU
!SUBROUTINE FOR COMBINATION
SUBROUTINE COMBINATION_CALC (N, K, FACT, COMBINATION)
IMPLICIT NONE
REAL N, K, FACT, COMBINATION
WRITE(*,*) ' WHAT IS THE VALUE OF N? '
READ(*,*) N
2 WRITE(*,*) ' WHAT IS THE VALUE OF K? '
READ(*,*) K
IF (K<0) THEN
WRITE(*,*) ' ERROR! VALUE OF K SHOULD BE MORE THAN 0! '
GO TO 2
ELSE IF (K>N)THEN
WRITE(*,*) ' ERROR! VALUE OF K SHOULD BE LESS THAN N! '
GO TO 2
ELSE
END IF
COMBINATION=FACT(N)/(FACT(N-K)*FACT(N))
WRITE(*,*) ' HENCE, THERE ARE ', COMBINATION, ' WAYS TO ARRANGE. '
CALL MENU
RETURN
END SUBROUTINE COMBINATION_CALC
!SUBROUTINE FOR PERMUTATION
SUBROUTINE PERMUTATION_CALC (N, K, FACT, PERMUTATION)
IMPLICIT NONE
REAL N, K, FACT, PERMUTATION
WRITE(*,*) ' WHAT IS THE VALUE OF N? '
READ(*,*) N
3 WRITE(*,*) ' WHAT IS THE VALUE OF K? '
READ(*,*) K
IF (K<0) THEN
WRITE(*,*) ' ERROR! VALUE OF K SHOULD BE MORE THAN 0! '
GO TO 3
ELSE IF (K>N) THEN
WRITE(*,*) ' ERROR! VALUE OF K SHOULD BE LESS THAN N! '
GO TO 3
ELSE
END IF
PERMUTATION=FACT(N)/FACT(N-K)
WRITE(*,*) ' HENCE THERE ARE', PERMUTATION,' WAYS TO ARRANGE. '
CALL MENU
RETURN
END SUBROUTINE PERMUTATION_CALC
!/*-------SUB PROGRAMS END-------*/
И я получаю ошибку во время выполнения всякий раз, когда я ввожу ввод 1 или 2, чтобы выбрать вариант для продолжения….
Во всплывающем окне ошибка отображается следующим образом:-
ОШИБКА ВО ВРЕМЯ ВЫПОЛНЕНИЯ
Попытка вызвать подпрограмму с аргументом номер три как реальную (kind=1), когда требуется процедура.
COMBINATION_CALC- в файле combinationpermutation.для в строке 62[ 0068] main- в файле combinationpermutation.для в строке 23 [ 00e2]
Насколько я знаю, аргумент номер три в COMBINATION_CALC — это «ФАКТ», который является функцией для вычисления факториала. Я не могу понять ошибку. Пожалуйста, направьте меня. Заранее спасибо..
Обновить
Я исправил ОШИБКУ во ВРЕМЯ выполнения, используя исправление, данное yosukesabai … моя программа теперь завершена .. но ПЕРЕПОЛНЕНИЕ целых ЧИСЕЛ — новая проблема для меня. Я изменил РЕАЛЬНОЕ объявление на ЦЕЛОЕ число (ВИД = 4).. Когда значения N и K больше 12… результирующий ответ для комбинации и перестановки будет большим… Могу ли я узнать, как это исправить?
Вот новый код для моей программы…
!/*-------MAIN PROGRAM STARTS-------*/
!PURPOSE: TO CALCULATE COMBINATIONS AND PERMUTATIONS
!CREATED BY: RETHNARAJ RAMBABU
!DATE: 28/10/2011
PROGRAM COMBINATION_PERMUTATION
IMPLICIT NONE
!DECLARATION OF VARIABLES
INTEGER CHOICE, N, K
INTEGER(KIND=4) COMBINATION, PERMUTATION
INTEGER, external :: FACT
!CHOICE MENU
1 WRITE(*,*) ' CHOOSE AN OPTION TO CONTINUE.. '
WRITE(*,*) ' 1. COMBINATION '
WRITE(*,*) ' 2. PERMUTATION '
WRITE(*,*) ' 3. EXIT PROGRAM '
!USER INPUT OF CHOICE
READ(*,*) CHOICE
!EXECUTION OF CODE BASED ON USER'S CHOICE
SELECT CASE(CHOICE)
CASE(1)
!CALLS SUBROUTINE FOR COMBINATION
CALL COMBINATION_CALC (N, K, FACT, COMBINATION)
GO TO 1
CASE(2)
!CALLS SUBROUTINE FOR PERMUTATION
CALL PERMUTATION_CALC (N, K, FACT, PERMUTATION)
GO TO 1
CASE(3)
!EXITS THE PROGRAM
STOP
CASE DEFAULT
!INVALID CHOICE LEADS TO MENU BACK
WRITE(*,*) 'INVALID CHOICE! PLEASE CHOOSE AN OPTION TO CONTINUE'
GO TO 1
END SELECT
END PROGRAM COMBINATION_PERMUTATION
!/*-------MAIN PROGRAM ENDS-------*/
!/*-------SUB PROGRAMS START-------*/
!FUNCTION FOR FACTORIAL
FUNCTION FACT(N)
IMPLICIT NONE
INTEGER N, P, I, FACT
P=1
DO I=1, N
P=P*I
END DO
FACT=P
RETURN
END FUNCTION
!SUBROUTINE FOR COMBINATION
SUBROUTINE COMBINATION_CALC (N, K, FACT, COMBINATION)
IMPLICIT NONE
INTEGER N, K, FACT
INTEGER(KIND=4) COMBINATION
WRITE(*,*) ' WHAT IS THE VALUE OF N? '
READ(*,*) N
2 WRITE(*,*) ' WHAT IS THE VALUE OF K? '
READ(*,*) K
IF (K<0) THEN
WRITE(*,*) ' ERROR! VALUE OF K SHOULD BE MORE THAN 0! '
GO TO 2
ELSE IF (K>N)THEN
WRITE(*,*) ' ERROR! VALUE OF K SHOULD BE LESS THAN N! '
GO TO 2
ELSE
END IF
COMBINATION=FACT(N)/(FACT(N-K)*FACT(K))
WRITE(*,*) ' HENCE, THERE ARE ', COMBINATION, ' WAYS TO ARRANGE. '
RETURN
END SUBROUTINE COMBINATION_CALC
!SUBROUTINE FOR PERMUTATION
SUBROUTINE PERMUTATION_CALC (N, K, FACT, PERMUTATION)
IMPLICIT NONE
INTEGER N, K, FACT
INTEGER(KIND=4)PERMUTATION
WRITE(*,*) ' WHAT IS THE VALUE OF N? '
READ(*,*) N
3 WRITE(*,*) ' WHAT IS THE VALUE OF K? '
READ(*,*) K
IF (K<0) THEN
WRITE(*,*) ' ERROR! VALUE OF K SHOULD BE MORE THAN 0! '
GO TO 3
ELSE IF (K>N) THEN
WRITE(*,*) ' ERROR! VALUE OF K SHOULD BE LESS THAN N! '
GO TO 3
ELSE
END IF
PERMUTATION=FACT(N)/FACT(N-K)
WRITE(*,*) ' HENCE THERE ARE', PERMUTATION,' WAYS TO ARRANGE. '
RETURN
END SUBROUTINE PERMUTATION_CALC
!/*-------SUB PROGRAMS END-------*/
Ответ №1:
В верхней части вашего кода,
PROGRAM COMBINATION_PERMUTATION
IMPLICIT NONE
!DECLARATION OF VARIABLES
REAL N, K, FACT, COMBINATION, PERMUTATION
INTEGER CHOICE
Здесь вы сказали, что ФАКТ реален, поэтому fortran предполагает, что это реальная переменная. Но вы имели в виду, что это ссылка на функцию, которую вы определили в том же файле. Так что пересмотрите, как
!DECLARATION OF VARIABLES
REAL N, K, COMBINATION, PERMUTATION
INTEGER CHOICE
REAL, external :: FACT
внешний — это способ fortran сказать, что это функция, которую вы определили где-то за пределами программного блока (программы, подпрограммы или функции)
(игнорируйте ниже здесь, если вам все равно)
Я замечаю, что нет смысла передавать ссылку на функцию. поэтому вы можете прекратить передачу функции и просто вызвать ее прямо из подпрограммы combination_calc. в этом случае n, k,combination — это три аргумента для подпрограммы, а внутри combination_calc у вас будет real, external :: fact
.
Комментарии:
1. добро пожаловать, я подумал, что вы получили свой ответ на полпути (указав, что факт является функцией)
2. привет, йосукэ… я обновил сообщение другим подвопросом для переполнения целых чисел .. пожалуйста, посмотрите
3. Вы знаете, что факториал взрывается как сумасшедший, бесполезный для вычислений. Вы не можете использовать формулу из учебника математики прямолинейно. избегайте вычисления факториала полностью и вычисляйте только те части, которые вам нужны (т.Е. n * (n-1) * ..* (n-k), а не n!) И если это все еще не работает, нужно искать какой-то метод аппроксимации.
Ответ №2:
Что касается переполнения целых чисел, объявите переменную P (внутри функции FACT) ВЕЩЕСТВЕННОЙ, а не ЦЕЛОЧИСЛЕННОЙ. ЦЕЛОЧИСЛЕННАЯ (4) переменная не может превышать 2^31
и 12! < 2^31 < 13!
Но будьте осторожны: переполнение может произойти и с РЕАЛЬНЫМ значением ( 35!
на моем компьютере : 34!=2.9523282E 38
). С ДВОЙНОЙ ТОЧНОСТЬЮ (REAL(8)) переполнение происходит в 171!
( 170! = 7.2574156153 306
)