Fortran What is the issue with this Fortran recursion problem?

  • Thread starter Thread starter hassamu
  • Start date Start date
  • Tags Tags
    Fortran Recursion
AI Thread Summary
The discussion revolves around a user learning Fortran and encountering issues with a recursive factorial program. The user’s implementation produces incorrect results, prompting them to seek help. An expert suggested implementing a stack pointer, which the user did not understand. Key points of the discussion include the necessity of using an IMPLICIT NONE statement to avoid implicit typing errors, as well as ensuring that the factorial function correctly handles negative inputs to prevent infinite loops. Suggestions were made to reorganize the code structure for clarity and to ensure proper handling of edge cases, such as returning 1 for both 0! and 1!. Additionally, it was noted that the program's integer type may limit the range of inputs, and using a larger integer kind could be beneficial for larger values. Overall, the conversation emphasizes the importance of handling input validation and proper function structuring in recursive programming.
hassamu
Messages
1
Reaction score
0
Hi everybody.
I am learning Fortran on my own, and I started doing simple examples like factorials, iterations, and stuff like that.
The problem comes in recursion, I'm trying to run this simple factorial program using recursion, but the outcome is completely wrong.
I asked to an expert in Fortran, but he said that I need to implement a stack pointer in order to keep track of all the values of my function, but I didn't understand him , and he is no more available this time.
Can somebody point out my mistakes or make suggestions about my program?
Thank you
Code:
recursive function factorial(myNumber) result (temp)
integer temp, myNumber
if(myNumber<=0) then
        temp = 1
        return
else
        temp = myNumber*factorial(myNumber-1)
        return
end if
end function factorial

program recursiveFactorial
      integer elNumero, resultado
      resultado = 1
      elNumero = 0
      write(*,*) 'Enter a positive integer:'
      read(*,*) elNumero
      resultado=factorial(elNumero)
      write(*,*) 'X!=',resultado
end program recursiveFactorial
 
Technology news on Phys.org
hassamu said:
Hi everybody.
I am learning Fortran on my own, and I started doing simple examples like factorials, iterations, and stuff like that.
The problem comes in recursion, I'm trying to run this simple factorial program using recursion, but the outcome is completely wrong.
I asked to an expert in Fortran, but he said that I need to implement a stack pointer in order to keep track of all the values of my function, but I didn't understand him , and he is no more available this time.
Can somebody point out my mistakes or make suggestions about my program?
Thank you
Code:
recursive function factorial(myNumber) result (temp)
integer temp, myNumber
if(myNumber<=0) then
        temp = 1
        return
else
        temp = myNumber*factorial(myNumber-1)
        return
end if
end function factorial

program recursiveFactorial
      integer elNumero, resultado
      resultado = 1
      elNumero = 0
      write(*,*) 'Enter a positive integer:'
      read(*,*) elNumero
      resultado=factorial(elNumero)
      write(*,*) 'X!=',resultado
end program recursiveFactorial

Caveat: I haven't done much Fortran for about a dozen years. Since you are getting some results, your compiler must adhere to the Fortran 90 (or later) standard. Recursion isn't supported in Fortran 77.

Here's a link to some recursion examples in Fortran 90: http://math.scu.edu/~dsmolars/ma60/notesforrec.html.

Your code looks OK to me except for one line in your recursive function. I would change this:
Code:
if(myNumber <= 0) then

to this:
Code:
if(myNumber == 1) then
 
hassamu said:
Hi everybody.
I am learning Fortran on my own, and I started doing simple examples like factorials, iterations, and stuff like that.
The problem comes in recursion, I'm trying to run this simple factorial program using recursion, but the outcome is completely wrong.
I asked to an expert in Fortran, but he said that I need to implement a stack pointer in order to keep track of all the values of my function, but I didn't understand him , and he is no more available this time.
Can somebody point out my mistakes or make suggestions about my program?
Thank you
Code:
recursive function factorial(myNumber) result (temp)
integer temp, myNumber
if(myNumber<=0) then
        temp = 1
        return
else
        temp = myNumber*factorial(myNumber-1)
        return
end if
end function factorial

program recursiveFactorial
      integer elNumero, resultado
      resultado = 1
      elNumero = 0
      write(*,*) 'Enter a positive integer:'
      read(*,*) elNumero
      resultado=factorial(elNumero)
      write(*,*) 'X!=',resultado
end program recursiveFactorial

A problem here is that you have not used an IMPLICIT NONE statement in your program and function to turn off implicit typing. Here "factorial" in your main program is a real quantity, but it is an integer in your function. You need to have:

Code:
integer factorial
or

Code:
integer,external::factorial
in your main program.

But you should always have IMPLICT NONE in both your main program, and all subroutines.


Also, you don't mention what kind of problems you are having, but by using the default integer you are restricting yourself to only small values for elNumero (for example, up to 12 for my compiler). If you go past this limit you will not get the answer, you'll just get garbage. You can choose a different KIND value for the integer to extend the range of the integers; for example, for my compiler you could use:

Code:
integer(kind=8):: elNumero, resultado
and similarly for all the other integer declarations. (Your compiler may use a different number than 8. )


To see what the largest value is that your variable can hold, you could add as a temporary line:

Code:
 print*,'The largest number here is ',huge(resultado)
right before the END PROGRAM line. At some point, for very large numbers, you might want to consider changing your program variables from integers to reals.
 
Mark44 said:
Caveat: I haven't done much Fortran for about a dozen years. Since you are getting some results, your compiler must adhere to the Fortran 90 (or later) standard. Recursion isn't supported in Fortran 77.

Here's a link to some recursion examples in Fortran 90: http://math.scu.edu/~dsmolars/ma60/notesforrec.html.

Your code looks OK to me except for one line in your recursive function. I would change this:
Code:
if(myNumber <= 0) then

to this:
Code:
if(myNumber == 1) then

No, that is wrong, because factorial 0 (written 0!) is 1.
Your modification would cause an infinite loop for an argument of 0
and for any negative value.
The original test is correct.
 
hassamu said:
Hi everybody.
I am learning Fortran on my own, and I started doing simple examples like factorials, iterations, and stuff like that.
The problem comes in recursion, I'm trying to run this simple factorial program using recursion, but the outcome is completely wrong.
I asked to an expert in Fortran, but he said that I need to implement a stack pointer in order to keep track of all the values of my function, but I didn't understand him , and he is no more available this time.
Can somebody point out my mistakes or make suggestions about my program?
Thank you
Code:
recursive function factorial(myNumber) result (temp)
integer temp, myNumber
if(myNumber<=0) then
        temp = 1
        return
else
        temp = myNumber*factorial(myNumber-1)
        return
end if
end function factorial

program recursiveFactorial
      integer elNumero, resultado
      resultado = 1
      elNumero = 0
      write(*,*) 'Enter a positive integer:'
      read(*,*) elNumero
      resultado=factorial(elNumero)
      write(*,*) 'X!=',resultado
end program recursiveFactorial

You should reorganize your code thus:
Code:
program recursiveFactorial
      IMPLICIT NONE
      integer elNumero, resultado
      resultado = 1
      elNumero = 0
      write(*,*) 'Enter a positive integer:'
      read(*,*) elNumero
      resultado=factorial(elNumero)
      write(*,*) 'X!=',resultado

CONTAINS

recursive function factorial(myNumber) result (temp)
integer temp, myNumber
if(myNumber<=0) then
        temp = 1
        return
else
        temp = myNumber*factorial(myNumber-1)
        return
end if
end function factorial

end program recursiveFactorial
 
Louisa said:
No, that is wrong, because factorial 0 (written 0!) is 1.
Your modification would cause an infinite loop for an argument of 0
and for any negative value.
The original test is correct.
My point was that it was silly to check for negative numbers. If the input value was 0 or 1, you could return 1 as a special case, but for values greater than 1, you could use recursion.
 
Louisa said:
You should reorganize your code thus:
Code:
program recursiveFactorial
      IMPLICIT NONE
      integer elNumero, resultado
      resultado = 1
      elNumero = 0
      write(*,*) 'Enter a positive integer:'
      read(*,*) elNumero
      resultado=factorial(elNumero)
      write(*,*) 'X!=',resultado

CONTAINS

recursive function factorial(myNumber) result (temp)
integer temp, myNumber
if(myNumber<=0) then
        temp = 1
        return
else
        temp = myNumber*factorial(myNumber-1)
        return
end if
end function factorial

end program recursiveFactorial

There is a problem with this code as well. If you pass a negative number to the factorial function, it will return 1, and that is incorrect.
 
Mark44 said:
My point was that it was silly to check for negative numbers. If the input value was 0 or 1, you could return 1 as a special case, but for values greater than 1, you could use recursion.

It is necessary to test for negative numbers.
If the recursive routine is presented with a negative argument,
it will loop forever.
 
Mark44 said:
There is a problem with this code as well. If you pass a negative number to the factorial function, it will return 1, and that is incorrect.

It is essential to have a test for negative.
Either there needs to be an error trap, or the routine returns a value, say 1.
If there is no test for zero, an infinite loop occurs when the
function is presented with a negative argument.
 

Similar threads

Replies
62
Views
12K
Replies
3
Views
2K
Replies
4
Views
2K
Replies
8
Views
4K
Replies
8
Views
2K
Replies
12
Views
3K
Replies
8
Views
4K
Back
Top