我在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
融资218000
出租5917.1429
我的结果是:0.006247000000000489
Excel结果为:0.00624616
Excel函数被称为:=IRR(T12:T73,0.01)
T12-T73与我正在使用的数字相同。
任何帮助将不胜感激,谢谢杰森
UPDATE
我通过更改下面的值来解决它。但现在表现太慢了。关于如何改进这个的任何想法?
IRRCalc(IRRval, 0.001)
//to
IRRCalc(IRRval, 0.0001)
inc = 0.000001;
//to
inc = 0.00000001;
快速浏览代码后,错误似乎与浮点精度错误有关。更多信息可以在这里找到: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;
在我看来,成为问题。
解决这个问题的方法是使用整数。因此,使用1代替0.000001而不是0.001,您将使用1000.然后将返回结果除以100000
我们修改了代码以实现性能和准确性。试试这个:
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;
}
这是一个浮点问题。您将要使用像BigDecimal.js这样的库来处理您的值。这是避免这个问题的唯一方法。
试试这个。
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;
}
我想建立在@Zohaib答案的基础上,但我想做的是在适当的地方显示未定义。我能做的最好就是让它等于零。我正在使用这个简单的数据集irr_arr=[-100, 100, 100, 100, 100,100]
。我很感激一些建议。
//IRRCALC funtion that handles irr going to infinity
function IRRCalc_test(CArray) {
min = 0.0;
max = 1.0;
c=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;
c++;
}
else {
max = guest;
c++;
}
if(c>=15){ return guest*100; }
} while(Math.abs(NPV) > 0.000001);
return guest*100;
}
// some testing
irr_arr=[-100, 100, 100, 100, 100,100]
irr_res_arr_expected=[0,0,61.8,83.93,92.76,96.6]
for(i=1;i<=irr_arr.length;i++){
console.log("irr_arr - ",irr_arr.slice(0,i));
console.log("IRRCalc - ",IRRCalc(irr_arr.slice(0,i)))
//console.log("irr_expected - ", irr_res_arr_expected[i-1])
//if(IRRCalc(irr_arr.slice(0,i))===parseFloat(irr_res_arr_expected[i-1]).toFixed(2)){console.log(i,"- TRUE")} else {console.log(i,"- FALSE")}
}
这是输出
irr_arr - [-100]
IRRCalc - 0.00 <<<<<<<<<<<<<<<<<<<------- this should be 'undefined' and not 'zero'
irr_arr - [-100, 100]
IRRCalc - 0.00
irr_arr - [-100, 100, 100]
IRRCalc - 61.80
irr_arr - [-100, 100, 100, 100]
IRRCalc - 83.93
irr_arr - [-100, 100, 100, 100, 100]
IRRCalc - 92.76
irr_arr - [-100, 100, 100, 100, 100, 100]
IRRCalc - 96.60
这是我想要产生的优点
不要将你的最小内部收益率设置为0.这就是你的答案。尝试让它变为负面。另外,不要尝试在一个数字上计算IRR。