如何在c#中计算成本

本文关键字:计算 | 更新日期: 2023-09-27 17:50:45

我试着从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的解决方案。

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

如何在c#中计算成本

看起来你不会在每次循环中改变你的本金,这意味着每个月的利息都是一样的。从你的问题中也不清楚你是否已经调整了初始余额,以考虑到开始期间的任何付款。

方法的基本逻辑应该是:

  • 计算结余
  • 从开始到结束的每个时间段
    • 使用余额计算支付的本金,并将其添加到累计总额
    • 从结余中扣除已付本金

计算每月支付的本金最简单的方法是将当月的利息从月供中扣除。这意味着提前计算每月付款是有意义的。计算月供和余额的公式可在此找到。

下面的方法应该给出与excel相同的结果(基于CUMPRINC MS页面上的示例,精确到小数点后10位;如果你需要更精确的话,你可能想摆弄一下这些类型)。

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