如何计算在C#中的Cumprinc?

我试图从Microsoft Excel中计算Cumprinc公式,如下所示:

 for (double i = start; i <= end; i++) { if (type > 0) { principal += payment - (payment * Math.Pow((1 + rate), (i - 2)) - payment) * rate; } else { principal+=payment-(payment*Math.Pow((1+rate),(i-1))-payment)*rate; } } 

但是,它提供了一个不同于Ms-excel的解决scheme。

我需要确切的逻辑来计算CUMPRINC公式。

看起来你不会在你的循环的每一次迭代中改变你的主体,这意味着每个月的兴趣将是相同的。 从您的问题来看,您是否已经调整了初始余额以考虑到开始期间的任何付款,这一点也不清楚。

你的方法的基本逻辑应该是:

  • 计算余额
  • 开始和结束之间的每个时期
    • 用剩余余额计算支付的本金,并将其加到累计总额中
    • 从余额中扣除本金

计算当月支付的本金最简单的方法是从当月开始计算利息,并从月度支付中扣除。 这意味着预先计算每月付款是有意义的。 计算每月支付和余额的公式可以在这里find。

下面的方法应该给出与excel相同的结果(根据CUMPRINC MS页面上的示例精确到10位小数;如果您需要更精确的话,可能需要使用types)。

 private static decimal CumPrinc(double rate, int periods, decimal pV, int start, int end, int type) { //adjust the start and end periods based on the type //if it's 1 then payments are at the beginning of the period //which is the same as the end of the previous period if (type == 1) { start -= 1; end -= 1; } //calculate the monthlyPayment decimal monthlyPayment = (decimal)((rate * (double)pV * Math.Pow((1 + rate), periods)) / (Math.Pow((1 + rate), periods) - 1)); //calculate the remaining balance decimal remainingBalance = (decimal)((Math.Pow((1 + rate), start - 1) * (double)pV) - (((Math.Pow((1 + rate), start - 1) - 1) / rate) * (double)monthlyPayment)); decimal principal = 0; for (int i = start; i <= end; i++) { //get the interest for the month decimal monthlyInterest = remainingBalance * (decimal)rate; //the principal for the month is the payment less the interest decimal monthlyPrincipal = monthlyPayment - monthlyInterest; //add the months principal to the running total principal += monthlyPrincipal; //deduct the months principal from the remaining balance remainingBalance -= monthlyPrincipal; } return principal; } 

一旦您有计算给定期间的剩余余额的方法,虽然您可以通过计算期初的剩余余额和期末的剩余余额来完全消除循环的需要,然后返回差额:

 private static decimal CumPrinc(double rate, int periods, decimal pV, int start, int end, int type) { //adjust the start and end periods based on the type //if it's 1 then payments are at the beginning of the period //which is the same as the end of the previous period if (type == 1) { start -= 1; end -= 1; } //calculate the monthlyPayment decimal monthlyPayment = (decimal)((rate * (double)pV * Math.Pow((1 + rate), periods)) / (Math.Pow((1 + rate), periods) - 1)); decimal remainingBalanceAtStart = (decimal)((Math.Pow((1 + rate), start - 1) * (double)pV) - (((Math.Pow((1 + rate), start - 1) - 1) / rate) * (double)monthlyPayment)); decimal remainingBalanceAtEnd = (decimal)((Math.Pow((1 + rate), end) * (double)pV) - (((Math.Pow((1 + rate), end) - 1) / rate) * (double)monthlyPayment)); return remainingBalanceAtEnd - remainingBalanceAtStart; }