【问题标题】:java compound interest with contributions formulajava复利与贡献公式
【发布时间】:2015-04-13 02:34:16
【问题描述】:

我目前正在尝试开发一个包含每月供款的复利计算器。我已经成功地能够使用以下代码行在没有每月供款的情况下进行复利计算,但无法弄清楚添加每月供款时的公式应该是什么。

double calculatedValue = (principalValue * Math.pow(1 + (interestRateValue/numberOfCompoundsValue), (termValue * numberOfCompoundsValue)));

当尝试通过贡献获得计算值时,我改变了这样做的方式。请参阅以下代码,我是如何处理这个问题的。

//The starting principal
double principalValue = 5000;

//Interest rate (%)
double interestRateValue = 0.05;

//How many times a year to add interest
int numberOfCompoundsValue = 4;

//The number of years used for the calculation
double termValue = 30;

//The monthly contribution amount
double monthlyContributionsValue = 400;

//How often interest is added. E.g. Every 3 months if adding interest 4 times in a year
int interestAddedEveryXMonths = 12/numberOfCompoundsValue;

//The total number of months for the calculation
int totalNumberOfMonths = (int)(12 * termValue);

    for(int i = 1; i <= totalNumberOfMonths; i++)
    {

        principalValue += monthlyContributionsValue;

        if(i % interestAddedEveryXMonths == 0)
        {
            principalValue += (principalValue * interestRateValue);
        }
    }

我认为这应该符合我的要求。每个月按供款金额增加本金,如果该月等于应添加利息的月份,则计算利息*利率并将其添加到本金中。

当使用上面的值时,我希望得到 $355,242.18 但得到 $10511941.97,这在我的银行帐户中看起来更好,但在我的计算中却没有。

如果有人能给我一些帮助或指出我哪里出错了,将不胜感激。

提前致谢

【问题讨论】:

  • 尝试调试一下就知道问题出在哪里了
  • 我已经对此进行了调试,一切看起来都像它应该做的那样,除了我不确定每次迭代应该计算的确切值之外。在盯着代码看太久之后,一定有一些非常明显的东西我错过了。

标签: java formula


【解决方案1】:

你的问题在这里:

principalValue += (principalValue * interestRateValue);

您每季度都增加一整年的利息,而您应该只增加一个季度的利息。您需要降低利率以获得合适的利率。

这是一个例子:

class CashFlow {
    private final double initialDeposit;
    private final double rate;
    private final int years;
    private final double monthlyContribution;
    private final int interestFrequency;

    CashFlow(double initialDeposit, double rate, int years,
             double monthlyContribution, int interestFrequency) {
        if ( years < 1 ) {
            throw new IllegalArgumentException("years must be at least 1");
        }

        if ( rate <= 0 ) {
            throw new IllegalArgumentException("rate must be positive");
        }

        if ( 12 % interestFrequency != 0 ) {
            throw new IllegalArgumentException("frequency must divide 12");
        }

        this.initialDeposit = initialDeposit;
        this.rate = rate;
        this.years = years;
        this.monthlyContribution = monthlyContribution;
        this.interestFrequency = interestFrequency;
    }

    public double terminalValue() {
        final int interestPeriod = 12 / interestFrequency;
        final double pRate = Math.pow(1 + rate, 1.0 / interestPeriod) - 1;
        double value = initialDeposit;

        for ( int i = 0; i < years * 12; ++i ) {
            value += monthlyContribution;

            if ( i % interestFrequency == interestFrequency - 1 ) {
                value *= 1 + pRate;
            }  
        }

        return value;
    }
}

class CompoundCalc {

    public static void main(String[] args) {
        CashFlow cf = new CashFlow(5000, 0.05, 30, 400, 3);
        System.out.println("Terminal value: " + cf.terminalValue());
    }
}

带输出:

run:
Terminal value: 350421.2302849443
BUILD SUCCESSFUL (total time: 0 seconds)

这接近您找到的 355,000 美元的价值。

您可以使用多种不同的约定来获取季度费率。将年利率除以 4 是一种简单实用的方法,但上面的 pow(1 + rate, 1 / 4) - 1 方法在理论上更合理,因为它在数学上等价于相应的年利率。

【讨论】:

    【解决方案2】:

    经过一些简短的测试,我得出的结论是:

    • 算错了你想要的价值 ($355,242.18)

    • 错误地问了你的问题

    您所描述的计算方法(5000 美元开始 + 30 年每月 400 美元的供款 + 每 3 个月的利息)可通过您提供的代码找到。从我所见,它给出的价值(10,511,941.97 美元)确实是正确的。我能提供的唯一其他建议是仅在需要时使用double(例如termValue 可以是intAND,只要您知道该值不会改变(例如interestRateValue)使用final。这将有助于避免大型程序中出现任何不可预见的错误。我希望这可以帮助您计算出您的兴趣计算器或回答您的任何问题。

    【讨论】:

    • 感谢保罗的意见。我所期待的答案来自一个在线复利计算器,所以假设这与我实际得到的结果相符。我设置的值现在是硬编码的,但稍后将由用户输入。例如,用户将能够为该期限输入 1.5 年。不过,我会记住你的建议。谢谢。
    • @ShaunD 没问题!我很高兴你能弄清楚。我在想你有计划稍后实现这个变量。如果您想将我的答案标记为“正确”,这将阻止人们将来尝试回答:)
    • 1000 万美元的价值绝对不正确,在这里。正确的未来价值确实非常接近 355,000 美元。
    【解决方案3】:
    static void Main(string[] args)
            {
                double monthlyDeposit;
                double rateOfInterest;
                double numberOfCompounds;
                double years;
                double futureValue = 0;
                double totalAmount = 0;
    Console.WriteLine("Compound Interest Calculation based on monthly deposits");
                Console.WriteLine("Monthly Deposit");
                monthlyDeposit = Convert.ToDouble(Console.ReadLine());
                Console.WriteLine("Rate Of Interest");
                rateOfInterest = Convert.ToDouble(Console.ReadLine());
                Console.WriteLine("Number of Compounds in a year");
                numberOfCompounds = Convert.ToDouble(Console.ReadLine());
                Console.WriteLine("Number of year");
                years = Convert.ToDouble(Console.ReadLine());
                futureValue = monthlyDeposit;
                for (int i = 1; i <= years * 12; i++)
                {
                    totalAmount = futureValue * (1 + (rateOfInterest / 100) / 12);
                    if (i == years * 12)
                        futureValue = totalAmount;
                    else
                        futureValue = totalAmount + monthlyDeposit;
                }
                Console.WriteLine("Future Value is=" + futureValue);
                Console.ReadLine();
    
            }
    
            //Output
            Compound Interest Calculation based on monthly Deposits
            Monthly Deposit
            1500
            Rate Of Interest
            7.5
            Number of Compounds in a year
            12
            Number of year
            1
            Future Value is=18748.2726237313
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-15
      • 2018-07-28
      • 2017-03-03
      • 2011-09-13
      • 1970-01-01
      • 1970-01-01
      • 2014-01-16
      相关资源
      最近更新 更多