2016-07-23 29 views
0

Ich schrieb den GNU Fortran-Code in zwei separate Dateien auf Code :: Blocks: main.f95, example.f95. main.f95 Inhalt:Fortran: Aufrufen anderer Funktionen in einer Funktion

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 Inhalt:

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 

Wenn ich diesen Code ausführen, der Ausgang ist:

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

Die Permutation und Kombination Funktionen funktionieren nicht richtig. Danke für die Antworten.

+1

Dies ist etwas, das viele C/C++ - Programmierer überrascht. "integer :: i = 42" ist NICHT äquivalent zu "integer :: i; i = 42', aber stattdessen 'integer, save :: i = 42'. Der Wert von "i" wird zwischen Anrufen beibehalten und nie auf 42 zurückgesetzt. – jlokimlin

Antwort

2

Ich glaube, Sie sind mit einem von Fortran's bekannten (Gottsuchern) bekannt geworden. Aber bevor ich das enthülle, muss ich fragen, wie viel Sie getestet haben? Ich lief Code, bekam das ungerade Ergebnis und dachte für eine Minute ...

dann ich die factorial Funktion für ein paar kleine Werte von x getestet, die

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 

erzeugt, die offensichtlich falsch ist. Es scheint also, dass Sie Ihren Code nicht richtig getestet haben, wenn überhaupt, bevor Sie um Hilfe gebeten haben. (Habe ich nicht getestet Ihre combination und permutation Funktionen.)

O tempora, o mores

Sie die Variable product_ in der Zeile initialisiert haben

integer :: product_ = 1, i 

und das bedeutet automatisch, dass product_ erwirbt das Attribut save, so dass sein Wert vom Aufruf zum Aufruf (Gotcha!) Gespeichert wird. Zu Beginn jedes Anrufs (außer dem ersten) hat product_ den Wert, den es am Ende des vorherigen Anrufs hatte.

Die Abhilfe ist einfach, initialisieren Sie nicht product_. Ändern

integer :: product_ = 1, i 

zu

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

noch Einfachere wäre nicht Ihre eigene Fakultätsfunktion zu schreiben, aber die intrinsische product Funktion zu verwenden, aber das ist eine andere Geschichte.