Javascript IRR(内部收益率)公式准确度

时间:2013-02-26 12:28:35

标签: javascript jquery excel math excel-formula

我在javascript中使用IRR函数来创建使用自己的IRR函数在excel中完成的计算。问题是我的很少,我不知道为什么。这是下面的代码。

var IRRval = [];

IRRval.push(-financed);
for (i = 0; i < period; i++) {
    IRRval.push(rental);
}

var IRR = IRRCalc(IRRval, 0.001) * 0.01;

function IRRCalc(CArray, guest) {
    inc = 0.000001;
    do {
        guest += inc;
        NPV = 0;
        for (var j=0; j < CArray.length; j++) {
            NPV += CArray[j] / Math.pow((1 + guest), j);
        }
    } while (NPV > 0);
    return guest * 100;
}

现在,如果你使用这些数字:


第24期

资助22000

出租1017.5000

我的结果是:0.008523000000000175

Excel结果为:0.008522918



第42期

Financed 218000

出租5917.1429

我的结果是:0.006247000000000489

Excel结果为:0.00624616


调用Excel函数:=IRR(T12:T73,0.01) T12-T73与我正在使用的数字相同。

非常感谢任何帮助,谢谢Jason

更新

我通过更改以下值解决了这个问题。但现在表现太慢了。关于如何改进这个的任何想法?

IRRCalc(IRRval, 0.001)

//to

IRRCalc(IRRval, 0.0001)

inc = 0.000001;

//to

inc = 0.00000001;

6 个答案:

答案 0 :(得分:6)

快速浏览代码后,错误似乎与浮点精度错误有关。可以在此处找到更多信息:http://ajaxian.com/archives/crock-on-floating-points-in-javascript

在较旧的javascript引擎中,如果你做了0.3 + 0.3,你会得到像0.600000000001

这样的东西

虽然今天大多数javascript引擎返回0.6,但问题仍然存在。一起添加浮动会导致意外结果。在你的情况下

inc = 0.000001;
guest += inc;
在我看来,问题就在于此。

解决这个问题的方法是使用整数。因此,而不是0.000001,你会使用1而不是0.001,你会使用1000.然后将你的返回结果除以100000

答案 1 :(得分:6)

我们修改了代码以实现性能和准确性。试试这个:

function IRRCalc(CArray) {

  min = 0.0;
  max = 1.0;
  do {
    guest = (min + max) / 2;
    NPV = 0;
    for (var j=0; j<CArray.length; j++) {
          NPV += CArray[j]/Math.pow((1+guest),j);
    }
    if (NPV > 0) {
      min = guest;
    }
    else {
      max = guest;
    }
  } while(Math.abs(NPV) > 0.000001);
  return guest * 100;
}

答案 2 :(得分:0)

这是一个浮点问题。您将要使用BigDecimal.js之类的库来处理您的值。这是避免这个问题的唯一方法。

答案 3 :(得分:0)

试试这个。

function NPV(discountRate, cashFlow){
    var npv = 0;
    for(var t = 0; t < cashFlow.length; t++) {
        npv += cashFlow[t] / Math.pow((1+ discountRate),t);
    }
    return npv;
}


function IRR(cashFlow,guess){
    guess = guess ? guess : 0.1;
    var npv;
    var cnt = 0;
    do
    {
        npv = NPV(guess,cashFlow);
        guess+= 0.001;

        cnt++;
    }
    while(npv > 0)

    return guess;
}

答案 4 :(得分:0)

不要将你的最小内部收益率设置为0.这就是你的答案。尝试让它变为负面。也不要尝试在一个数字上计算IRR。

答案 5 :(得分:0)

这可能是编写计算的更好方法。这样,代码就可以计算负IRR或高于100%的IRR的实例。

        var IRRval = [];

        IRRval.push(-financed);
            for (i = 0; i < period; i++) {
            IRRval.push(rental);
        }
        var IRR = IRRCalc(IRRval, 0.001) * 0.01;

        function IRRCalc(CArray) {
            var r = 0
            min = -1.0;
            max = 10000.0;
            do {
                guest = (min + max) / 2;
                NPV = 0;
                for (var j = 0; j < CArray.length; j++) {
                    NPV += CArray[j] / Math.pow((1 + guest), j);
                }
                if (NPV > 0) {
                    min = guest;
                }
                else {
                    max = guest;
                }
                r++
            } while (r < 100);
            return guest * 100
        }