简体   繁体   English

简单的java递归,不可预测的程序行为

[英]Simple java recursion, unpredictable program behavior

Trivial program to calculate compound interest, I = P(1+n)^y.计算复利的简单程序,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):输出如下(注意 YEARLY 计算正确但未按预期返回):

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.当我调试时,执行按预期进入 if (years == 1),但随后也会进入以下 else 块。 How can it enter both branches?它如何进入两个分支? Please advise;请指教; I've been racking my brains, and restarting the computer and NetBeans didn't help.我绞尽脑汁,重新启动计算机,NetBeans 也没有用。

You're not entering the else block after the years==1 if block, you're simply adding yearly to every recursive call.您不会在 years==1 if 块之后进入 else 块,您只是将每年添加到每个递归调用中。

Change the return statement in the else block to将 else 块中的 return 语句更改为

return calculate(yearly, interest, years - 1)

from

return yearly + calculate(yearly, interest, years - 1)

No, execution does not enter the else block after that if block.不,执行不会进入该 if 块之后的 else 块。 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.请注意,在终端 if 之后,执行将通过前面堆栈中的 else 语句逐步退回。 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.结果累积在第一个参数中,无需在方法的最后一行添加 yearly 的值。 The logic can also be a bit simplified:逻辑也可以简化一点:

    if (years == 1){
        return yearly;
    }
    return calculate(yearly, interest, years - 1);

The else branch is entered on any call where years > 1 , especially for years == 2 . else分支在任何years > 1调用中输入,尤其是对于years == 2 Form there, you call calculate with years == 1 , which is when you enter the if -statement in question.在那里,您使用years == 1调用calculate ,这是您输入相关if语句的时间。 Now after the return in this if -statement is executed, execution resumes on the previous level of the recursion where it stopped.现在,在执行此if语句中的return之后,执行将在它停止的递归的前一级恢复。 This is within the else block, after the recursive call.这是在递归调用之后的else块中。 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.查看years的值,会看到ifreturn执行后,从1变为2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM