Ошибка времени выполнения в fortran

#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 )