Javascript IRR (внутренняя норма прибыли) Формула Точность

Я использую функцию IRR в javascript для создания вычисления a, которое выполняется в excel, используя собственную 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, 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; 

После быстрого чтения прочитайте свой код, ошибка, похоже, связана с ошибкой точности с плавающей запятой . Более подробную информацию можно найти здесь: 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

Мы изменили код для достижения производительности и точности. Попробуй это:

 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 Answer, но то, что я хотел бы сделать, показывается неопределенным, если это необходимо. Лучшее, что я могу сделать, это получить его равным нулю. Я использую этот простой набор данных 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 

вот предел того, что я пытаюсь произвести

введите описание изображения здесь

Не устанавливайте IRR min равным 0. Именно это ограничивает ваш ответ. Попробуйте позволить ему пойти отрицательно. Также не пытайтесь вычислять IRR на одном номере.

  • Как Excel успешно округляет плавающие числа, хотя они неточны?
  • Вычисление оптимальной комбинации автобусов для пассажиров?
  • Как найти ближайший номер в Excel и вернуть соответствующую ячейку?
  • Произвольно генерировать x целых чисел с суммой y с Excel
  • Поиск всех возможных комбинаций для букмекеров
  • Инкрементные числа из списка, Excel
  • Различные вычисления в SQL Server и Excel
  • Excel 2007 VBA Calculations Wrong
  • Масштабированная функция дополнительной ошибки, erfcx (x), вычисление, исключающее арифметическое переполнение - VBA / Excel
  • Увеличение среднего отклонения с увеличением размера выборки в Excel NORMINV ()
  • Если выражение, использующее формат времени в Excel
  • Давайте будем гением компьютера.