Calculating Interest with Recursive Function

  • Thread starter Thread starter James889
  • Start date Start date
  • Tags Tags
    Interest
AI Thread Summary
The discussion revolves around creating a recursive function to calculate bank interest over a specified number of years. The main issue raised is the need for a static variable to retain the value of the interest rate across recursive calls, which leads to a compilation error due to improper initialization. The solution involves correcting the initialization of the interest rate variable, ensuring it is treated as a floating-point number by using explicit decimal points. This prevents integer division errors that can lead to incorrect calculations. The conversation emphasizes the importance of understanding data types and the implications of integer versus floating-point arithmetic in programming. Additionally, alternative function structures are discussed, highlighting the difference between tail-recursive and non-tail-recursive implementations. The participants stress the value of recognizing and correcting common coding mistakes to improve clarity and functionality in programming.
James889
Messages
190
Reaction score
1
Hi,

I am trying to write a simple recursive function for calculating money in the bank after a certain amount of years.


However i run into trouble since i need the new_base variable to be static(i need it to "remember" the base from the previous run) But trying to compile the program i get the error:
"Initializer element is not constant"

How would you solve this?

Code:
double recursive(double base, int runs) {

     static double m_rate = 1 + (10/100);   /* Ten percent interest*/
      
      double new_base = (base*m_rate);
      

      if (runs != 0)
      return recursive(new_base,runs-1);

      else 
      return new_base;
}

int main() {
printf("%.2f",recursive(100,10));
return 0;
}
 
Technology news on Phys.org
EDIT: I just deleted part 1 of what I said since I misunderstood your question.It is a good practice to denote floating point variables with an explicit dot, i.e.
Code:
static double m_rate = 1. + (10./100.);
rather than
Code:
static double m_rate = 1 + (10/100);
This not only makes the code clearer (even to yourself because you immediately see what kind of algebra your number belongs to) but also prevents a lot of newbie mistakes (just try both version and try to find out the difference for yourself).
 
Last edited:
You don't need a static for new_base. You don't even need new_base as you could use:

...
return recursive(base*m_rate,runs-1);
...

You don't have to worry about the program "remembering" each instance of base on each call, since each call creates a new instance of base on the stack during operation of the recursive function.

Also for m_rate all the numbers to the right of the = are defaulted to integer values, so m_rate will = 1.00 in this statement:

static double m_rate = 1 + (10/100);

As mentioned above, you need to change this to:

static double m_rate = 1. + (10./100.);

Note that there's only one instance of m_rate, having the static inside the function just makes the name local, the vairable will still be stored in the global data area, which is probably what you want.
 
Thank you rcgldr and Timo!

It works now :)
 
Timo said:
EDIT: I just deleted part 1 of what I said since I misunderstood your question.


It is a good practice to denote floating point variables with an explicit dot, i.e.
Code:
static double m_rate = 1. + (10./100.);
rather than
Code:
static double m_rate = 1 + (10/100);
This not only makes the code clearer (even to yourself because you immediately see what kind of algebra your number belongs to) but also prevents a lot of newbie mistakes (just try both version and try to find out the difference for yourself).

To elaborate on what Timo said, in the second example above, m_rate is initialized to 1.0, which is not what you want at all.

10/100 == 0. The reason for this is that both operands are implicitly int values, so integer division is performed.

After that, 0 is added to 1, resulting in 1.

Finally, the int value 1 is promoted to a double value, and then stored in m_rate.
 
There goes "... try to find out the difference for yourself ..." :P
 
Timo said:
There goes "... try to find out the difference for yourself ..." :P
It's easy to see that the two different sets of code produce different results. What might not be so easy to see is why that occurs.
 
That's why these small exercises are so useful, you always learn something.
 
Mark44 said:
It's easy to see that the two different sets of code produce different results. What might not be so easy to see is why that occurs.
Understanding "try to find out the difference for yourself" as "try to realize that two different sets of code produce different results, but don't worry about the reason" is a rather peculiar interpretation of yours.
 
  • #10
You can also write the function in the following way:
Code:
double recursiveNotTail(double base, int runs) {

     static double m_rate = 1. + (10./100.);   /* Ten percent interest*/

     if (runs != 0)
        return m_rate*recursiveNotTail(base,runs-1);

     else
        return base;
}

This version has a disadvantage though: it is not tail-recursive. For tail-recursion have a look at this explanation.
 
  • #11
Mark44 said:
It's easy to see that the two different sets of code produce different results. What might not be so easy to see is why that occurs.

Timo said:
Understanding "try to find out the difference for yourself" as "try to realize that two different sets of code produce different results, but don't worry about the reason" is a rather peculiar interpretation of yours.
That's an incorrect interpretation of what I said, which is more along these lines - an inexperienced programmer can readily recognize that two sets of code produce different results, but might not understand why that is so, particularly when there are a bunch of type conversions going on. A C programmer who writes 10/100, and expects that it will produce 0.1, is by definition inexperienced.

As far as "don't worry about the reason" is concerned, that is completely off base, since I explained exactly what was going on.
 
  • #12
Mark44 said:
As far as "don't worry about the reason" is concerned, that is completely off base, since I explained exactly what was going on.
Indeed. You may now proceed to read post #6. I'll break out of this loop now, though.
 
  • #13
Timo, please dispense with the condescension. I did read post #6, and responded to it (and quoted it) in post #7. From some of your comments it seems to me that you aren't reading what I have written.

For the 3rd time, I don't believe that the OP would have understood why the examples you posted in #2 produced different results. In post #3 I gave an explanation of why his code would not have worked as he/she expected. If you have a problem with that, we can continue offline by PM.
 

Similar threads

Replies
1
Views
2K
Replies
1
Views
1K
Replies
11
Views
1K
Replies
4
Views
3K
Replies
5
Views
12K
Back
Top