What is the issue with this Fortran recursion problem?

  • Context: Fortran 
  • Thread starter Thread starter hassamu
  • Start date Start date
  • Tags Tags
    Fortran Recursion
Click For Summary

Discussion Overview

The discussion revolves around a Fortran program that implements recursion to calculate factorials. Participants are exploring issues related to the correctness of the code, particularly focusing on the recursive function's behavior and potential mistakes in the implementation.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant notes that the recursive function may require a stack pointer to track values, but expresses confusion about this suggestion.
  • Another participant suggests changing the condition from "if(myNumber <= 0)" to "if(myNumber == 1)", arguing that the original condition is incorrect.
  • A different participant counters that the original condition is correct because factorial(0) is defined as 1, and changing it would lead to an infinite loop for 0 or negative values.
  • Concerns are raised about the lack of an IMPLICIT NONE statement, which could lead to implicit typing issues between the main program and the recursive function.
  • One participant mentions that using default integers may limit the range of values for elNumero, suggesting the use of a different KIND value for integers to handle larger numbers.
  • Another participant proposes reorganizing the code to include the recursive function within the main program using the CONTAINS statement.

Areas of Agreement / Disagreement

Participants express differing opinions on the correctness of the condition in the recursive function and the necessity of certain coding practices, indicating that multiple competing views remain without consensus on the best approach.

Contextual Notes

Some participants highlight limitations related to implicit typing and the range of integer values, suggesting that these issues could affect the program's functionality but do not resolve them.

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 5 ·
Replies
5
Views
2K
  • · Replies 62 ·
3
Replies
62
Views
13K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 8 ·
Replies
8
Views
4K
  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 12 ·
Replies
12
Views
3K
  • · Replies 8 ·
Replies
8
Views
4K