简体   繁体   中英

Fortran: Calling other functions in a function

I wrote the GNU Fortran code in two separate files on Code::Blocks: main.f95, example.f95. main.f95 content:

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

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

When I run this code, the output is:

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

The permutation and combination functions don't work properly. Thanks for answers.

I think you've fallen foul of one of Fortran's well-known (to those who know it) gotchas. But before revealing that I have to ask how much testing you did ? I ran your code, got the odd result and thought for a minute ...

then I tested the factorial function for a few small values of x which produced

 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

which is obviously wrong. So it seems that you didn't test your code properly, if at all, before asking for help. (I didn't test your combination and permutation functions.)

O tempora, o mores

You've initialised the variable product_ in the line

 integer :: product_ = 1, i

and this automatically means that product_ acquires the attribute save so its value is stored from invocation to invocation (gotcha !). At the start of each call (other than the first) product_ has the value it had at the end of the previous call.

The remedy is simple, don't initialise product_ . Change

 integer :: product_ = 1, i

to

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

Simpler still would be to not write your own factorial function but to use the intrinsic product function but that's another story.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM