2016-07-23 4 views
0

Я написал код GNU Fortran в двух отдельных файлах по коду :: Блоки: main.f95, example.f95. Содержание main.f95: содержаниеФортран: вызов других функций в функции

program testing 

    use example 

    implicit none 
    integer :: a, b 

    write(*,"(a)", advance="no") "Enter first number: " 
    read(*,*) a 

    write(*,"(a)", advance="no") "Enter second number: " 
    read(*,*) b 

    write(*,*) factorial(a) 
    write(*,*) permutation(a, b) 
    write(*,*) combination(a, b) 

end program testing 

example.f95:

module example 


contains 


    integer function factorial(x) 

    implicit none 
    integer, intent(in) :: x 
    integer :: product_ = 1, i 

    if (x < 1) then 

     factorial = -1 

    else if (x == 0 .or. x == 1) then 

     factorial = 1 

    else 

     do i = 2, x 
      product_ = product_ * i 
     end do 

     factorial = product_ 

    end if 

    end function factorial 


    real function permutation(x, y) 

    implicit none 
    integer, intent(in) :: x, y 
    permutation = factorial(x)/factorial(x - y) 

    end function permutation 


    real function combination(x, y) 

    implicit none 
    integer, intent(in) :: x, y 

    combination = permutation(x, y)/factorial(y) 

    end function combination 


end module example 

Когда я запускаю этот код, выход:

Enter first number: 5 
Enter second number: 3 
    120 
    0.00000000  
    0.00000000  

функции перестановки и комбинации не работают должным образом. Спасибо за ответы.

+1

Это то, что удивляет многих программистов на C/C++. 'integer :: i = 42' НЕ EQUIVALENT для' integer :: i; i = 42', но вместо этого «integer, save :: i = 42'. Значение 'i' поддерживается между вызовами и никогда не сбрасывается до 42. – jlokimlin

ответ

2

Я думаю, что вы попали в фол одного из известных Fortran (для тех, кто это знает), gotchas. Но прежде чем открыть, что я должен спросить, сколько вы проверили? Я побежал код, получил странный результат, и на минуту задумался ...

я тестировал функцию factorial для нескольких небольших значений x, которые производили

factorial   1 =   1 
factorial   2 =   2 
factorial   3 =   12 
factorial   4 =   288 
factorial   5 =  34560 
factorial   6 =  24883200 
factorial   7 = 857276416 
factorial   8 = -511705088 
factorial   9 = 1073741824 
factorial   10 =   0 

, который, очевидно, неправильно. Похоже, что вы не тестировали свой код должным образом, если вообще, прежде чем обращаться за помощью. (Я не проверял свою combination и permutation функции.)

О Темпоры, о нравах

Вы инициализированные переменной product_ в строке

integer :: product_ = 1, i 

и это автоматически означает, что product_ получает атрибут save, поэтому его значение сохраняется от вызова к вызову (gotcha!). В начале каждого вызова (кроме первого) product_ имеет значение, имевшееся в конце предыдущего вызова.

Средство простое, не инициализируйте product_. Изменение

integer :: product_ = 1, i 

в

integer :: product_ , i 
... 
product_ = 1 

Simpler еще бы не написать свою собственную функцию факториала, но использовать внутреннюю product функцию, но это другая история.