问题
Trivial program to calculate compound interest, I = P(1+n)^y.
public class Interest {
public static void main(String[] args){
double sum = calculate(1000,10,3);
System.out.println(sum);
//sanity check, using non-recursive formula:
double amt = 1000*(Math.pow(1 + 0.1, 3));
System.out.println(amt);
}
public static double calculate(double initialAmount, double interest, int years){
double yearly = initialAmount + initialAmount*(interest/100);
System.out.println("calculate is called with P = " + initialAmount + ", interest = "+interest+", and years = " + years);
System.out.println("This year's amount: "+yearly);
if (years <= 0){
return initialAmount;
}
if (years == 1){
return yearly;
}
else {
return yearly + calculate(yearly, interest, years - 1);
}
}
}
The output is as follows (notice that YEARLY is calculated correctly but not returned as expected):
debug:
calculate is called with P = 1000.0, interest = 10.0, and years = 3
This year's amount: 1100.0
calculate is called with P = 1100.0, interest = 10.0, and years = 2
This year's amount: 1210.0
calculate is called with P = 1210.0, interest = 10.0, and years = 1
This year's amount: 1331.0
3641.0
1331.0000000000005
When I debug, execution enters if (years == 1) as expected, but then also enters the following else block. How can it enter both branches? Please advise; I've been racking my brains, and restarting the computer and NetBeans didn't help.
回答1:
The else branch is entered on any call where years > 1, especially for years == 2. Form there, you call calculate with years == 1, which is when you enter the if-statement in question. Now after the return in this if-statement is executed, execution resumes on the previous level of the recursion where it stopped. This is within the else block, after the recursive call. When you check the value of years, you will see that it changes from 1 to 2 after the return in the if is executed.
回答2:
No, execution does not enter the else block after that if block. That's impossible. If it appears that way, then it seems you are misunderstanding your debugger. Note that after the terminal if, execution will be stepping back through the else statements in the preceding stacks. But it will not enter. Only step back into.
The result is accumulated in the first parameter, there's no need to add the value of yearly on the last line of your method. The logic can also be a bit simplified:
if (years == 1){
return yearly;
}
return calculate(yearly, interest, years - 1);
回答3:
You're not entering the else block after the years==1 if block, you're simply adding yearly to every recursive call.
Change the return statement in the else block to
return calculate(yearly, interest, years - 1)
from
return yearly + calculate(yearly, interest, years - 1)
来源:https://stackoverflow.com/questions/33698898/simple-java-recursion-unpredictable-program-behavior