Apache的POI率式不一致性与长期(Apache POI rate formula incons

2019-08-04 16:19发布

为了模拟Excel的速率函数,我使用的Apache POI率函数我从SVN抓起:

private double calculateRate(double nper, double pmt, double pv, double fv, double type, double guess) {

  //FROM MS http://office.microsoft.com/en-us/excel-help/rate-HP005209232.aspx
  int FINANCIAL_MAX_ITERATIONS = 20; //Bet accuracy with 128
  double FINANCIAL_PRECISION = 0.0000001; //1.0e-8

  double y, y0, y1, x0, x1 = 0, f = 0, i = 0;
  double rate = guess;
  if (Math.abs(rate) < FINANCIAL_PRECISION) {
     y = pv * (1 + nper * rate) + pmt * (1 + rate * type) * nper + fv;
  }
  else {
     f = Math.exp(nper * Math.log(1 + rate));
     y = pv * f + pmt * (1 / rate + type) * (f - 1) + fv;
  }
  y0 = pv + pmt * nper + fv;
  y1 = pv * f + pmt * (1 / rate + type) * (f - 1) + fv;

  // Find root by the Newton secant method
  i = x0 = 0.0;
  x1 = rate;
  while ((Math.abs(y0 - y1) > FINANCIAL_PRECISION) && (i < FINANCIAL_MAX_ITERATIONS)) {
     rate = (y1 * x0 - y0 * x1) / (y1 - y0);
     x0 = x1;
     x1 = rate;

     if (Math.abs(rate) < FINANCIAL_PRECISION) {
        y = pv * (1 + nper * rate) + pmt * (1 + rate * type) * nper + fv;
     }
     else {
        f = Math.exp(nper * Math.log(1 + rate));
        y = pv * f + pmt * (1 / rate + type) * (f - 1) + fv;
     }

     y0 = y1;
     y1 = y;
     ++i;
  }
  return rate;

}

对于calculateRate(120,28.1,-2400,0,0,0.1)),则输出是相同的Excel中:0.599

但是,如果我尝试同样的计算,这个时间值:

calculateRate(360, 15.9, -2400, 0, 0, 0.1))

在Excel中,我得到0.580,且程序回到-1.1500428517726355。 任何提示?

Answer 1:

还有一堆事情是不对的代码,你在你的问题已经粘贴。

它假定的速度总是发现(不是真的),并为实例没有规定时,没有发现率。

一些声明将抛出这本来是可以避免用更合适的编程语句中的错误。 举例来说,从你的代码下面的语句:

f = Math.exp(nper * Math.log(1 + rate));

试图找到一个负数或零值的记录时,这会抛出一个错误。 它可能已被改写为

f = Math.pow(1 + rate, nper);

在迭代计算的评论指出,这是编程割线法 ,但迭代计算是检查错了变量的收敛。 它测试的是一个未来价值的融合,当它应该测试的利率趋同。

我复制粘贴你的代码在记事本中,并去掉了Java的变量声明,并取代了这些JavaScript的变量声明与您的样本数据来测试代码。 而且,正如我所说的,代码停在第二次迭代,因为未来值的差异超出约束错误,并因为有一个地方没有测试,看速度是否被发现,该代码返回利率为是和一个这是不对的。

我不知道为什么这个代码实例它会报告正确率是与第一个数据集的情况下工作。 我建议功能的重新编码以正确的方式。



Answer 2:

public double rate(double nper, double pmt, double pv)
{
    //System.out.println("function rate : " + nper + " " + pmt + " pv " + pv);

    double error = 0.0000001;
    double high =  1.00;
    double low = 0.00;

    double rate = (2.0 * (nper * pmt - pv)) / (pv * nper);

    while(true) {
        // Check for error margin
        double calc = Math.pow(1 + rate, nper);
        calc = (rate * calc) / (calc - 1.0);
        calc -= pmt / pv;

        if (calc > error) {
            // Guess is too high, lower the guess
            high = rate;
            rate = (high + low) / 2;
        } 
        else if (calc < -error) {
            // Guess is too low, higher the guess.
            low = rate;
            rate = (high + low) / 2;
        } 
        else {
            // Acceptable guess
            break;
        }
    }

    //System.out.println("Rate : " + rate);
    return rate;
}

例如: =RATE(60, 2112500, 65000000)返回0.025198; 同样用Excel(正确的)。



文章来源: Apache POI rate formula inconsistency with long periods