IRR в poi возвращает NaN, но правильное значение в Excel - PullRequest
0 голосов
/ 11 октября 2019

Когда я вычисляю значение Irr, использую apache / poi, я получаю Double.NaN, но те же входные данные в Excel я получаю отрицательное значение.

Так почему же они возвращают другое значение?

inputs here:

irr(-1.0601017230994111E8,19150.63,44505.08,22997.34,33936.39,27265.92,2127.66,2108.63,886.53,2482.27,4305.12,3421.58,65644.12,1020.51,2659.57,3191.49,20284508.4,1881279.27,11675415.09,7557862.28,921090.46,622104.32,289267.36,183.41,886.53, 0.1)

1 Ответ

1 голос
/ 11 октября 2019

Для меня это дает #NUM! ошибка в текущем apache poi 4.1.0, а не NaN.

Проблема связана с вашим предположением. В IRR-функции указано:

Guess Необязательно. Число, которое, по вашему мнению, близко к результату IRR.

Microsoft Excel использует итеративную технику для расчета IRR. Начиная с догадки, IRR циклически перебирает вычисления, пока результат не станет точным в пределах 0,00001 процента. Если IRR не может найти результат, который работает после 20 попыток, #NUM! возвращается значение ошибки.

В большинстве случаев нет необходимости указывать предположение для расчета IRR. Если предположение опущено, оно принимается равным 0,1 (10 процентов).

Если IRR дает #NUM! значение ошибки, или если результат не соответствует ожидаемому, попробуйте еще раз с другим значением для предположения.

Результат вашего IRR будет -0.050193141 в Excel. Но ваше предположение 0,1. Таким образом, используя это предположение, внутренняя функция apache poi IRR не находит результат, который является точным в пределах 0,00001 процента после 20 попыток. Так что #NUM! возвращается значение ошибки.

Почему функция apache poi IRR отличается от функции Excel? Хорошо, потому что эта часть Excel не является открытым исходным кодом. Так что никто на самом деле не знает, как это работает.

Использование предположения из -0.1 работает для меня.

Пример:

import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

class ExcelEvaluateIRR {

 public static void main(String[] args) throws Exception {

  try (Workbook workbook = new XSSFWorkbook(); 
       FileOutputStream fileout = new FileOutputStream("Excel.xlsx") ) {

   Double[] values = new Double[] {
    -1.0601017230994111E8,
    19150.63,
    44505.08,
    22997.34,
    33936.39,
    27265.92,
    2127.66,
    2108.63,
    886.53,
    2482.27,
    4305.12,
    3421.58,
    65644.12,
    1020.51,
    2659.57,
    3191.49,
    20284508.4,
    1881279.27,
    11675415.09,
    7557862.28,
    921090.46,
    622104.32,
    289267.36,
    183.41,
    886.53
   };

   Sheet sheet = workbook.createSheet();
   Row row = null;
   Cell cell = null;
   for (int r = 0; r < values.length; r++) {
    row = sheet.createRow(r);
    cell = row.createCell(0);
    cell.setCellValue(values[r]);
   }
   row = sheet.createRow(values.length);
   cell = row.createCell(0);
   //cell.setCellFormula("IRR(A1:A" + values.length + ",0.1)"); // will not work
   cell.setCellFormula("IRR(A1:A" + values.length + ",-0.1)"); // will work
   FormulaEvaluator formulaEvaluator = workbook.getCreationHelper().createFormulaEvaluator();
   CellValue cellValue = formulaEvaluator.evaluate(cell);
   System.out.println(cellValue);

   workbook.write(fileout);
  }

 }
}
...