# Calculating interest C

1. Jan 5, 2012

### James889

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 (Text):

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;
}

2. Jan 5, 2012

### Timo

EDIT: I jsut 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 (Text):
static double m_rate = 1. + (10./100.);
rather than
Code (Text):
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: Jan 5, 2012
3. Jan 5, 2012

### rcgldr

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.

4. Jan 5, 2012

### James889

Thank you rcgldr and Timo!

It works now :)

5. Jan 5, 2012

### Staff: Mentor

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.

6. Jan 5, 2012

### Timo

There goes "... try to find out the difference for yourself ..." :P

7. Jan 5, 2012

### Staff: Mentor

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.

8. Jan 5, 2012

### James889

That's why these small exercises are so useful, you always learn something.

9. Jan 7, 2012

### Timo

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. Jan 7, 2012

### Edgardo

You can also write the function in the following way:
Code (Text):

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. Jan 7, 2012

### Staff: Mentor

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. Jan 8, 2012

### Timo

Indeed. You may now proceed to read post #6. I'll break out of this loop now, though.

13. Jan 8, 2012

### Staff: Mentor

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.

Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook