8

私は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は私が使用しているのと同じ図です。

助けていただければ幸いです、ありがとうジェイソン

アップデート

以下の値を変更して解決しました。しかし、今ではパフォーマンスが遅すぎます。これを改善する方法について何かアイデアはありますか?

IRRCalc(IRRval, 0.001)

//to

IRRCalc(IRRval, 0.0001)

inc = 0.000001;

//to

inc = 0.00000001;
4

7 に答える 7

12

パフォーマンスと精度を実現するためにコードを変更しました。これを試して:

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;
}
于 2013-10-24T07:59:57.113 に答える
9

コードをざっと読んだ後、エラーは浮動小数点精度エラーに関連しているようです。詳細については、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 で割ります。

于 2013-02-26T12:36:06.680 に答える
1

@Zohaib Answer から構築したいと思いますが、必要に応じて undefined を表示したいと思います。私にできる最善のことは、ゼロに等しくすることです。この単純なデータセットを使用してい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

これが私が作成しようとしているもののExcelです

ここに画像の説明を入力

于 2015-12-20T22:45:42.153 に答える
1

確かに浮動小数点の問題です。BigDecimal.jsのようなライブラリを使用して値を処理する必要があります。これが、この問題を回避する唯一の方法です。

于 2013-02-26T14:44:21.523 に答える