I was reading up about the difference between tail recursion and Traditional recursion and find it mentioned that "Tail Recursion however is a form of recursion that doesn’t use any stack space, and thus is a way to use recursion safely."'
I am struggling to understand how.
Comparing finding factorial of a number using the Traditional and tail recursion
Traditional recursion
/* traditional recursion */
fun(5);
int fun(int n)
{
if(n == 0)
return 1;
return n * fun(n-1);
}
Here, the call stack would look like
5 * fact(4)
|
4 * fact(3)
|
3 * fact(2)
|
2 * fact(1)
|
1 * fact(0)
|
1
Tail recursion
/* tail recursion */
fun(5,1)
int fun(int n, int sofar)
{
int ret = 0;
if(n == 0)
return sofar;
ret = fun(n-1,sofar*n);
return ret;
}
However, even here, the variable 'sofar' would hold - 5,20,60,120,120 at different points.
But once return is called from the base case which is recursive invocation #4, it still has to return 120 to recursive invocation #3, then to#2, #1 and back to main.
So, I mean to say that the stack is used and everytime you return to the previous call, the variables at that point in time can be seen, which means it is being saved at each step.
Unless, the tail recursion was written like below, I am not being able to understand how it saves stack space.
/* tail recursion */
fun(5,1)
int fun(int n, int sofar)
{
int ret = 0;
if(n == 0)
return 'sofar' back to main function, stop recursing back; just a one-shot return
ret = fun(n-1,sofar*n);
return ret;
}
PS : I have read few threads on SO and came to understand what tail recursion is, however, this question is more related to why it saves stack space. I could not find a similar question where this was discussed.
The trick is that if the compiler notices the tail recursion, it can compile a goto instead. It will generate something like the following code:
int fun_optimized(int n, int sofar)
{
start:
if(n == 0)
return sofar;
sofar = sofar*n;
n = n-1;
goto start;
}
And as you can see, the stack space is reused for each iteration.
Note that this optimization can only be done if the recursive call is the very last action in the function, that is tail recursion (try doing it manually to the non-tail case and you'll see that's just impossible).
A function call is tail recursive when function call (recursive) is performed as final action. Since the current recursive instance is done executing at that point, no need to maintaining its stack frame.
In this case, creating a stack frame on top of the current stack frame is nothing more than waste.
When compiler recognizes a recursion to be a tail recursion then it does not create nesting stack frames for each of the call instead it use the current stack frame. This is equivalent in effect to a goto statement. This make make that function call iterative rather recursive.
Note that in traditional recursion, every recursive call must have to complete before compiler performing the multiplication operations:
fun(5)
5 * fun(4)
5 * (4 * fun(3))
5 * (4 * (3 * fun(2)))
5 * (4 * (3 * (2 * fun(1))))
5 * (4 * (3 * (2 * 1)))
120
Nested stack frame needed in this case. Look at wiki for more information.
In case of tail recursion, with each call of fun, variable sofar is updated:
fun(5, 1)
fun(4, 5)
fun(3, 20)
fun(2, 60)
fun(1, 120)
120
No need to save stack frame of current recursive call.
Related
Very simply, what is tail-call optimization?
More specifically, what are some small code snippets where it could be applied, and where not, with an explanation of why?
Tail-call optimization is where you are able to avoid allocating a new stack frame for a function because the calling function will simply return the value that it gets from the called function. The most common use is tail-recursion, where a recursive function written to take advantage of tail-call optimization can use constant stack space.
Scheme is one of the few programming languages that guarantee in the spec that any implementation must provide this optimization, so here are two examples of the factorial function in Scheme:
(define (fact x)
(if (= x 0) 1
(* x (fact (- x 1)))))
(define (fact x)
(define (fact-tail x accum)
(if (= x 0) accum
(fact-tail (- x 1) (* x accum))))
(fact-tail x 1))
The first function is not tail recursive because when the recursive call is made, the function needs to keep track of the multiplication it needs to do with the result after the call returns. As such, the stack looks as follows:
(fact 3)
(* 3 (fact 2))
(* 3 (* 2 (fact 1)))
(* 3 (* 2 (* 1 (fact 0))))
(* 3 (* 2 (* 1 1)))
(* 3 (* 2 1))
(* 3 2)
6
In contrast, the stack trace for the tail recursive factorial looks as follows:
(fact 3)
(fact-tail 3 1)
(fact-tail 2 3)
(fact-tail 1 6)
(fact-tail 0 6)
6
As you can see, we only need to keep track of the same amount of data for every call to fact-tail because we are simply returning the value we get right through to the top. This means that even if I were to call (fact 1000000), I need only the same amount of space as (fact 3). This is not the case with the non-tail-recursive fact, and as such large values may cause a stack overflow.
Let's walk through a simple example: the factorial function implemented in C.
We start with the obvious recursive definition
unsigned fac(unsigned n)
{
if (n < 2) return 1;
return n * fac(n - 1);
}
A function ends with a tail call if the last operation before the function returns is another function call. If this call invokes the same function, it is tail-recursive.
Even though fac() looks tail-recursive at first glance, it is not as what actually happens is
unsigned fac(unsigned n)
{
if (n < 2) return 1;
unsigned acc = fac(n - 1);
return n * acc;
}
ie the last operation is the multiplication and not the function call.
However, it's possible to rewrite fac() to be tail-recursive by passing the accumulated value down the call chain as an additional argument and passing only the final result up again as the return value:
unsigned fac(unsigned n)
{
return fac_tailrec(1, n);
}
unsigned fac_tailrec(unsigned acc, unsigned n)
{
if (n < 2) return acc;
return fac_tailrec(n * acc, n - 1);
}
Now, why is this useful? Because we immediately return after the tail call, we can discard the previous stackframe before invoking the function in tail position, or, in case of recursive functions, reuse the stackframe as-is.
The tail-call optimization transforms our recursive code into
unsigned fac_tailrec(unsigned acc, unsigned n)
{
TOP:
if (n < 2) return acc;
acc = n * acc;
n = n - 1;
goto TOP;
}
This can be inlined into fac() and we arrive at
unsigned fac(unsigned n)
{
unsigned acc = 1;
TOP:
if (n < 2) return acc;
acc = n * acc;
n = n - 1;
goto TOP;
}
which is equivalent to
unsigned fac(unsigned n)
{
unsigned acc = 1;
for (; n > 1; --n)
acc *= n;
return acc;
}
As we can see here, a sufficiently advanced optimizer can replace tail-recursion with iteration, which is far more efficient as you avoid function call overhead and only use a constant amount of stack space.
TCO (Tail Call Optimization) is the process by which a smart compiler can make a call to a function and take no additional stack space. The only situation in which this happens is if the last instruction executed in a function f is a call to a function g (Note: g can be f). The key here is that f no longer needs stack space - it simply calls g and then returns whatever g would return. In this case the optimization can be made that g just runs and returns whatever value it would have to the thing that called f.
This optimization can make recursive calls take constant stack space, rather than explode.
Example: this factorial function is not TCOptimizable:
from dis import dis
def fact(n):
if n == 0:
return 1
return n * fact(n-1)
dis(fact)
2 0 LOAD_FAST 0 (n)
2 LOAD_CONST 1 (0)
4 COMPARE_OP 2 (==)
6 POP_JUMP_IF_FALSE 12
3 8 LOAD_CONST 2 (1)
10 RETURN_VALUE
4 >> 12 LOAD_FAST 0 (n)
14 LOAD_GLOBAL 0 (fact)
16 LOAD_FAST 0 (n)
18 LOAD_CONST 2 (1)
20 BINARY_SUBTRACT
22 CALL_FUNCTION 1
24 BINARY_MULTIPLY
26 RETURN_VALUE
This function does things besides call another function in its return statement.
This below function is TCOptimizable:
def fact_h(n, acc):
if n == 0:
return acc
return fact_h(n-1, acc*n)
def fact(n):
return fact_h(n, 1)
dis(fact)
2 0 LOAD_GLOBAL 0 (fact_h)
2 LOAD_FAST 0 (n)
4 LOAD_CONST 1 (1)
6 CALL_FUNCTION 2
8 RETURN_VALUE
This is because the last thing to happen in any of these functions is to call another function.
Probably the best high level description I have found for tail calls, recursive tail calls and tail call optimization is the blog post
"What the heck is: A tail call"
by Dan Sugalski. On tail call optimization he writes:
Consider, for a moment, this simple function:
sub foo (int a) {
a += 15;
return bar(a);
}
So, what can you, or rather your language compiler, do? Well, what it can do is turn code of the form return somefunc(); into the low-level sequence pop stack frame; goto somefunc();. In our example, that means before we call bar, foo cleans itself up and then, rather than calling bar as a subroutine, we do a low-level goto operation to the start of bar. Foo's already cleaned itself out of the stack, so when bar starts it looks like whoever called foo has really called bar, and when bar returns its value, it returns it directly to whoever called foo, rather than returning it to foo which would then return it to its caller.
And on tail recursion:
Tail recursion happens if a function, as its last operation, returns
the result of calling itself. Tail recursion is easier to deal with
because rather than having to jump to the beginning of some random
function somewhere, you just do a goto back to the beginning of
yourself, which is a darned simple thing to do.
So that this:
sub foo (int a, int b) {
if (b == 1) {
return a;
} else {
return foo(a*a + a, b - 1);
}
gets quietly turned into:
sub foo (int a, int b) {
label:
if (b == 1) {
return a;
} else {
a = a*a + a;
b = b - 1;
goto label;
}
What I like about this description is how succinct and easy it is to grasp for those coming from an imperative language background (C, C++, Java)
GCC C minimal runnable example with x86 disassembly analysis
Let's see how GCC can automatically do tail call optimizations for us by looking at the generated assembly.
This will serve as an extremely concrete example of what was mentioned in other answers such as https://stackoverflow.com/a/9814654/895245 that the optimization can convert recursive function calls to a loop.
This in turn saves memory and improves performance, since memory accesses are often the main thing that makes programs slow nowadays.
As an input, we give GCC a non-optimized naive stack based factorial:
tail_call.c
#include <stdio.h>
#include <stdlib.h>
unsigned factorial(unsigned n) {
if (n == 1) {
return 1;
}
return n * factorial(n - 1);
}
int main(int argc, char **argv) {
int input;
if (argc > 1) {
input = strtoul(argv[1], NULL, 0);
} else {
input = 5;
}
printf("%u\n", factorial(input));
return EXIT_SUCCESS;
}
GitHub upstream.
Compile and disassemble:
gcc -O1 -foptimize-sibling-calls -ggdb3 -std=c99 -Wall -Wextra -Wpedantic \
-o tail_call.out tail_call.c
objdump -d tail_call.out
where -foptimize-sibling-calls is the name of generalization of tail calls according to man gcc:
-foptimize-sibling-calls
Optimize sibling and tail recursive calls.
Enabled at levels -O2, -O3, -Os.
as mentioned at: How do I check if gcc is performing tail-recursion optimization?
I choose -O1 because:
the optimization is not done with -O0. I suspect that this is because there are required intermediate transformations missing.
-O3 produces ungodly efficient code that would not be very educative, although it is also tail call optimized.
Disassembly with -fno-optimize-sibling-calls:
0000000000001145 <factorial>:
1145: 89 f8 mov %edi,%eax
1147: 83 ff 01 cmp $0x1,%edi
114a: 74 10 je 115c <factorial+0x17>
114c: 53 push %rbx
114d: 89 fb mov %edi,%ebx
114f: 8d 7f ff lea -0x1(%rdi),%edi
1152: e8 ee ff ff ff callq 1145 <factorial>
1157: 0f af c3 imul %ebx,%eax
115a: 5b pop %rbx
115b: c3 retq
115c: c3 retq
With -foptimize-sibling-calls:
0000000000001145 <factorial>:
1145: b8 01 00 00 00 mov $0x1,%eax
114a: 83 ff 01 cmp $0x1,%edi
114d: 74 0e je 115d <factorial+0x18>
114f: 8d 57 ff lea -0x1(%rdi),%edx
1152: 0f af c7 imul %edi,%eax
1155: 89 d7 mov %edx,%edi
1157: 83 fa 01 cmp $0x1,%edx
115a: 75 f3 jne 114f <factorial+0xa>
115c: c3 retq
115d: 89 f8 mov %edi,%eax
115f: c3 retq
The key difference between the two is that:
the -fno-optimize-sibling-calls uses callq, which is the typical non-optimized function call.
This instruction pushes the return address to the stack, therefore increasing it.
Furthermore, this version also does push %rbx, which pushes %rbx to the stack.
GCC does this because it stores edi, which is the first function argument (n) into ebx, then calls factorial.
GCC needs to do this because it is preparing for another call to factorial, which will use the new edi == n-1.
It chooses ebx because this register is callee-saved: What registers are preserved through a linux x86-64 function call so the subcall to factorial won't change it and lose n.
the -foptimize-sibling-calls does not use any instructions that push to the stack: it only does goto jumps within factorial with the instructions je and jne.
Therefore, this version is equivalent to a while loop, without any function calls. Stack usage is constant.
Tested in Ubuntu 18.10, GCC 8.2.
Note first of all that not all languages support it.
TCO applys to a special case of recursion. The gist of it is, if the last thing you do in a function is call itself (e.g. it is calling itself from the "tail" position), this can be optimized by the compiler to act like iteration instead of standard recursion.
You see, normally during recursion, the runtime needs to keep track of all the recursive calls, so that when one returns it can resume at the previous call and so on. (Try manually writing out the result of a recursive call to get a visual idea of how this works.) Keeping track of all the calls takes up space, which gets significant when the function calls itself a lot. But with TCO, it can just say "go back to the beginning, only this time change the parameter values to these new ones." It can do that because nothing after the recursive call refers to those values.
Look here:
http://tratt.net/laurie/tech_articles/articles/tail_call_optimization
As you probably know, recursive function calls can wreak havoc on a stack; it is easy to quickly run out of stack space. Tail call optimization is way by which you can create a recursive style algorithm that uses constant stack space, therefore it does not grow and grow and you get stack errors.
The recursive function approach has a problem. It builds up a call stack of size O(n), which makes our total memory cost O(n). This makes it vulnerable to a stack overflow error, where the call stack gets too big and runs out of space.
Tail call optimization (TCO) scheme. Where it can optimize recursive functions to avoid building up a tall call stack and hence saves the memory cost.
There are many languages who are doing TCO like (JavaScript, Ruby and few C) whereas Python and Java do not do TCO.
JavaScript language has confirmed using :) http://2ality.com/2015/06/tail-call-optimization.html
We should ensure that there are no goto statements in the function itself .. taken care by function call being the last thing in the callee function.
Large scale recursions can use this for optimizations, but in small scale, the instruction overhead for making the function call a tail call reduces the actual purpose.
TCO might cause a forever running function:
void eternity()
{
eternity();
}
In a functional language, tail call optimization is as if a function call could return a partially evaluated expression as the result, which would then be evaluated by the caller.
f x = g x
f 6 reduces to g 6. So if the implementation could return g 6 as the result, and then call that expression it would save a stack frame.
Also
f x = if c x then g x else h x.
Reduces to f 6 to either g 6 or h 6. So if the implementation evaluates c 6 and finds it is true then it can reduce,
if true then g x else h x ---> g x
f x ---> h x
A simple non tail call optimization interpreter might look like this,
class simple_expresion
{
...
public:
virtual ximple_value *DoEvaluate() const = 0;
};
class simple_value
{
...
};
class simple_function : public simple_expresion
{
...
private:
simple_expresion *m_Function;
simple_expresion *m_Parameter;
public:
virtual simple_value *DoEvaluate() const
{
vector<simple_expresion *> parameterList;
parameterList->push_back(m_Parameter);
return m_Function->Call(parameterList);
}
};
class simple_if : public simple_function
{
private:
simple_expresion *m_Condition;
simple_expresion *m_Positive;
simple_expresion *m_Negative;
public:
simple_value *DoEvaluate() const
{
if (m_Condition.DoEvaluate()->IsTrue())
{
return m_Positive.DoEvaluate();
}
else
{
return m_Negative.DoEvaluate();
}
}
}
A tail call optimization interpreter might look like this,
class tco_expresion
{
...
public:
virtual tco_expresion *DoEvaluate() const = 0;
virtual bool IsValue()
{
return false;
}
};
class tco_value
{
...
public:
virtual bool IsValue()
{
return true;
}
};
class tco_function : public tco_expresion
{
...
private:
tco_expresion *m_Function;
tco_expresion *m_Parameter;
public:
virtual tco_expression *DoEvaluate() const
{
vector< tco_expression *> parameterList;
tco_expression *function = const_cast<SNI_Function *>(this);
while (!function->IsValue())
{
function = function->DoCall(parameterList);
}
return function;
}
tco_expresion *DoCall(vector<tco_expresion *> &p_ParameterList)
{
p_ParameterList.push_back(m_Parameter);
return m_Function;
}
};
class tco_if : public tco_function
{
private:
tco_expresion *m_Condition;
tco_expresion *m_Positive;
tco_expresion *m_Negative;
tco_expresion *DoEvaluate() const
{
if (m_Condition.DoEvaluate()->IsTrue())
{
return m_Positive;
}
else
{
return m_Negative;
}
}
}
I am learning recursion in my current class and the idea is a little tricky for me. From my understanding, when we build a function it will run as many times until our "base case" is satisfied. What I am wondering is how this looks and is returned on the stack. For an example I wrote the following function for a simple program to count how many times a digit shows up in an integer.
What does this look and work in a stack frame view? I don't completely understand how the returning works. I appreciate the help!
int count_digits(int n, int digit) {
// Base case: When n is a single digit.
if (n / 10 == 0) {
// Check if n is the same as the digit.
// When recursion hits the base case it will end the recursion.
if (n == digit) {
return 1;
} else {
return 0;
}
} else {
if (n % 10 == digit) {
return (1 + count_digits(n / 10, digit));
} else {
return (count_digits(n / 10, digit));
}
}
}
What does this look and work in a stack frame view? I don't completely understand how the returning works. I appreciate the help!
Let's try to build the solution bottom-up.
If you called the function - int count_digits(int n, int digit) as count_digits(4, 4) what would happen ?
This is the base case of your solution so it is very easy to see what is the return value. Your function would return 1.
Now, let's add one more digit and call the function like- count_digits(42, 4). What would happen ?
Your function will check the last digit which is 2 and compare with 4 since they are not equal so it will call the function count_digits(4, 4) and whatever is the returned value, will be returned as the result of count_digits(42, 4).
Now, let's add one more digit and call the function like - count_digits(424, 4). What would happen ?
Your function will check the last digit which is 4 and compare with 4 since they are equal so it will call the function count_digits(42, 4) and whatever is the returned value, will be returned by adding 1 to it. Since, number of 4s in 424 is 1 + number of 4s in 42. The result of count_digits(42,4) will be calculated exactly like it was done previously.
The recursive function builds up the solution in a top-down manner. If there are n digits initially, then your answer is (0 or 1 depending on the last digit) + answer with n-1 digits. And this process repeats recursively. So, your recursive code, reduces the problems by one digit at a time and it depends on the result of the immediate sub-problem.
You can use the C++ tutor at pythontutor.com website for step by step visualization of the stack frame. http://pythontutor.com/cpp.html#mode=edit
You can also try with smaller inputs and add some debug output to help you track and see how recursion works.
Check this stackoverflow answer for understanding what a stack frame is - Explain the concept of a stack frame in a nutshell
Check this stackoverflow answer for understanding recursion -
Understanding recursion
If you would like more help, please let me know in comments.
I have this code in VBA (looping through the array a() of type double):
bm = 0 'tot
b = 0 'prev
For i = 24 To 0 Step -1
BP = b 'prevprev = prev
b = bm 'prev = tot
bm = T * b - BP + a(i) 'tot = a(i) + T * prev - prevprev
Next
p = Exp(-xa * xa) * (bm - BP) / 4 '* (tot - prevprev)/4
I'm putting this in F#. Clearly I could use an array and mutable variables to recreate the VBA. And maybe this is an example of the right time to use mutable that I've seen hinted at. But why not try to do it the most idiomatic way?
I could write a little recursive function to replicate the loop. But it kind of feels like littering to hang out a little sub-loop that has no meaning on its own as a standalone, named function.
I want to do it with List functions. I have a couple ideas, but I'm not there yet. Anyone get this in a snap??
The two vague ideas I have are: 1. I could make two more lists by chopping off one (and two) elements and adding zero-value element(s). And combine those lists. 2. I'm wondering if a list function like map can take trailing terms in the list as arguments. 3. As a general question, I wonder if this might be a case where an experienced person would say that this problem screams for mutable values (and if so does that dampen my enthusiasm for getting on the functional boat).
To give more intuition for the code: The full function that this is excerpted from is a numerical approximation for the cumulative normal distribution. I haven't looked up the math behind this one. "xa" is the absolute value of the main function argument "x" which is the number of standard deviations from zero. Without working through the proof, I don't think there's much more to say than: it's just a formula. (Oh and maybe I should change the variable names--xa and bm etc are pretty wretched. I did put suggestions as comments.)
It's just standard recursion. You make your exit condition and your recur condition.
let rec calc i prevPrev prev total =
if i = 0 then // exit condition; do your final calc
exp(-xa * xa) * (total - prevPrev) / 4.
else // recur condition, call again
let newPrevPrev = prev
let newPrev = total
let newTotal = (T * newPrev - newPrevPrev + a i)
calc (i-1) newPrevPrev newPrev newTotal
calc 24 initPrevPrev initPrev initTotal
or shorter...
let rec calc i prevPrev prev total =
if i = 0 then
exp(-xa * xa) * (total - prevPrev) / 4.
else
calc (i-1) prev total (T * total - prev + a i)
Here's my try at pulling the loop out as a recursive function. I'm not thrilled about the housekeeping to have this stand alone, but I think the syntax is neat. Aside from an error in the last line, that is, where the asterisk in (c * a.Tail.Head) gets the red squiggly for float list not matching type float (but I thought .Head necessarily returned float not list):
let rec RecurseIt (a: float list) c =
match a with
| []-> 0.0
| head::[]-> a.Head
| head::tail::[]-> a.Head + (c * a.Tail) + (RecurseIt a.Tail c)
| head::tail-> a.Head + (c * a.Tail.Head) - a.Tail.Tail.Head + (RecurseIt a.Tail c)
Now I'll try list functions. It seems like I'm going to have to iterate by element rather than finding a one-fell-swoop slick approach.
Also I note in this recursive function that all my recursive calls are in tail position I think--except for the last one which will come one line earlier. I wonder if this creates a stack overflow risk (ie, prevents the compiler from treating the recursion as a loop (if that's the right description), or if I'm still safe because the algo will run as a loop plus just one level of recursion).
EDIT:
Here's how I tried to return a list instead of the sum of the list (so that I could use the 3rd to last element and also sum the elements), but I'm way off with this syntax and still hacking away at it:
let rec RecurseIt (a: float list) c =
match a with
| []-> []
| head::[]-> [a.Head]
| head::tail::[]-> [a.Head + (c * a.Tail)] :: (RecurseIt a.Tail c)
| head::tail-> [a.Head + (c * a.Tail.Head) - a.Tail.Tail.Head] :: (RecurseIt a.Tail c)
Here's my try at a list function. I think the problem felt more complicated than it was due to confusing myself. I just had some nonsense with List.iteri here. Hopefully this is closer to making sense. I hoped some List. function would be neat. Didn't manage. For loop not so idiomatic I think. :
for i in 0 .. a.Length - 1 do
b::
a.Item(i) +
if i > 0 then
T * b.Item(i-1) -
if i > 1 then
b.Item(i-2)
else
0
else
0
hello i have this piece of code that i coded based on some other recursion and factorial programs
but my problem is that i am really confused as to how it stored the value and kept it and then returned it at the end
int factorialfinder(int x)
{
if (x == 1)
{
return 1;
}else
{
return x*factorialfinder(x-1);
}
}
int main()
{
cout << factorialfinder(5) << endl;
}
so 5 goes in, and gets multiplied by 4 by calling its function again and again and again, then it gets to one and it returns the factorial answer
why? i have no idea how it got stored, why is return 1 returning the actual answer, what is it really doing?
Source: Image is taken from: IBM Developers website
Just take a look at the picture above, you will understand it better. The number never gets stored, but gets called recursively to calculate the output.
So when you call the fact(4) the current stack is used to store every parameter as the recursive calls occur down to factorialfinder(1). So the calculation goes like this: 5*4*3*2*1.
int factorialfinder(int x)
{
if (x == 1) // HERE 5 is not equal to 1 so goes to else
{
return 1;
}else
{
return x*factorialfinder(x-1); // returns 5*4*3*2*1 when x==1 it returns 1
}
}
Hope this helps.
Return 1 is not returning the actual answer. It's just returning the answer to calling
factorialfinder(1);
which happens in your code.
In any program, a call stack is a space in memory that is used to keep track of function calls. Space from this memory is used to store the arguments to a function, as well as the return value of that function. Whenever some function A calls another function B, A gets the return value of B from that space.
A recursive function is nothing special, it's just an ordinary function calling another function (that happens to be itself). So really, when a recursive function F calls itself, it's calling another function: F calls F', which calls F'', which calls F''', etc. It's just that F, F'', F''' etc. execute the same code, just with different inputs.
The expression if (x == 1) is there to check when this process should be stopped.
The return value of F''' is used by F''. The return value of F'' is used by F'. The return value of F' is used by F.
In Factorial of some number, the operation is (n) * (n-1) * (n-2) * .... * (1).
I've highlighted the 1; this is the condition that's being checked.
A recursive function breaks a big problem down into smaller cases.
Going over your program:
call factorialfinder with 5, result is stored as 5 * factorialfinder(4)
call factorialfinder with 4, result is stored as 5 * 4 * factorialfinder(3)
call factorialfinder with 3, result is stored as 5 * 4 * 3 * factorialfinder(2)
call factorialfinder with 2, result is stored as 5 * 4 * 3 * 2 * factorialfinder(1)
call factorialfinder with 1, result is stored as 5 * 4 * 3 * 2 * 1
in essence it combines the result of a stack of calls to factorialfinder until you hit your base case, in this case x = 1.
Well, the factorial function can be written using recursion or not, but the main consideration in the recursion is that this one uses the system stack, so, each call to the function is a item in the system stack, like this (read from the bottom to the top):
Other consideration in the recursion function is that this one has two main code piece:
The base case
The recursion case
In the base case, the recursive function returns the element that bounds the algorithm, and that stop the recursion. In the factorial this element is 1, because mathematically the factorial of number one is 1 by definition. For other numbers you don't know the factorial, because of that, you have to compute by using the formula, and one implementation of it is using recursion, so the recursive case.
Example:
The factorial of 5, the procedure is: 5*4*3*2*1 = 120, note you have to multiply each number from the top value until number 1, in other words, until the base case takes place which is the case that you already knew.
#include<iostream>
using namespace std;
int factorial(int n);
int main()
{
int n;
cout << "Enter a positive integer: ";
cin >> n;
cout << "Factorial of " << n << " = " << factorial(n);
return 0;
}
int factorial(int n)
{
if(n > 1)
return n * factorial(n - 1);
else
return 1;
}
I'm new to concept of recursion. I want to write a recursive function which take a float and integer as argument and call it recursively in a way that the float value remain constant and integer value changes
I write the following code:
#include <stdio.h>
float sum(float f, int k)
{
static float c;
c = f - k;
c = sum(f, k - 1);
return c;
}
int main()
{
float f, g = 10.00;
int i = 5;
f = sum(g, i);
printf("the sum of integer and float = %f", f);
}
When I compile it it shows no errors but when I run the program it shows a segmentation fault.
My question are following:
what is wrong with the code?
why it is showing segmentation error?
how to use recursion in a function which has more than one argument?
Please explain me with some example of recursive function which has two arguments.
The code is wrong because it can never end (I presume it fails with a stackoverflow error).
For recursion, you need two things
A base case
A recursive case that moves towards the base case
Looks like you've only got the second. I suspect sum should return when k is zero. Something like this hopefully makes sense:
float sum(float f, int k) {
if (k <= 0) {
// The base case
return f;
} else {
// The recursive case. This does one step of the work
// and moves towards the base case
return 1 + sum(f, k - 1);
}
}
Your recursion does not have a base (non-recursive), terminating case.
Every call to sum makes a recursive call to itself, this continues till your stackoverflows, resulting in a seg fault.
The recursion never stops, and eventually you run out of stack. You need to decide when it is time to stop the recursion. for example, if k equals 0 you don't call sum again, but exit with return.
float sum(float f ,int k)
{
static float c;
if (k > 0)
{
c=f-k; /// <<< why is this here? you ignore the value and overwrite it in the next step.
c=sum(f,k-1);
}
return c;
}
Of course there are additional problems: having c as static may be a problem that will affect the correctness of the calculation, and also the place I marked looks suspicious because you loose the value and overwrite it with the subsequent call to sum.
How about this?
#include <stdio.h>
float sum(float f, int k, float c) {
if (k == 0)
return c;
sum(f, k - 1, f - k);
}
The first thing I see is that your recursion has no termination. It will go on forever. Perhaps you want:
float sum(float f ,int k)
{
static float c;
c=f-k;
if (k != 0)
c=sum(f,k-1);
return c;
}
So that when k is zero the recursion stops. You had a stack overflow.
When you do recursion you need a status to end it.
So your code with changes:
#include <stdio.h>
float sum(float f, int k)
{
if(k == 0) return f;
return 1 + sum(f,k-1);
}
int main()
{
float f, g = 10.00;
int i = 5;
f = sum(g, i);
printf("the sum of integer and float = %f", f);
}
With that code, and your example f=10.00 and i=5
Call sum(10.0, 5)
return 1 + sum(10.0, 4)
1 + sum(10.0, 3)
1 + sum(10.0, 2)
1 + sum(10.0, 1)
1 + sum(10.0, 0)
10
1 + 10 = 11
1 + 11 = 12
1 + 12 = 13
1 + 13 = 14
1 + 14 = 15
return 15;
I don't understand what the "sum" function is for. Is it supposed to be adding f and k? In which case, there is no recursion; you should just add f and k: return f + k.
But to try to answer your questions:
There is no base case. This is the cause of the infinite recursion. Every recursive function needs a base case which is a condition under which it does not recurse. Your function recurses no matter what; therefore it will always recurse forever.
When recursion segfaults, it's usually due to a stack overflow (no pun intended); it means you are recursing forever and eventually running out of space.
You can use recursion in a function with more than one argument, just the same as any other function. Just call it with whatever the new values are for the next iteration.
Note that you often have a "constant" value, that doesn't change during the recursion. To do that, you just pass the value unchanged on the recursive call, so the same value is available at each step.