mirror of https://github.com/apache/poi.git
[github-733] Fix rate order in Mirr function. Thanks to Aleksandrs Jansons. This closes #733
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1922095 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
0d63f9a814
commit
edb9aeaca5
|
@ -56,23 +56,20 @@ public class Mirr extends MultiOperandNumericFunction {
|
|||
@Override
|
||||
protected double evaluate(double[] values) throws EvaluationException {
|
||||
|
||||
double financeRate = values[values.length-1];
|
||||
double reinvestRate = values[values.length-2];
|
||||
double financeRate = values[values.length-2];
|
||||
double reinvestRate = values[values.length-1];
|
||||
|
||||
double[] mirrValues = Arrays.copyOf(values, values.length - 2);
|
||||
|
||||
boolean mirrValuesAreAllNegatives = true;
|
||||
for (double mirrValue : mirrValues) {
|
||||
mirrValuesAreAllNegatives &= mirrValue < 0;
|
||||
}
|
||||
if (mirrValuesAreAllNegatives) {
|
||||
return -1.0d;
|
||||
}
|
||||
|
||||
boolean mirrValuesAreAllPositives = true;
|
||||
for (double mirrValue : mirrValues) {
|
||||
mirrValuesAreAllNegatives &= mirrValue < 0;
|
||||
mirrValuesAreAllPositives &= mirrValue > 0;
|
||||
}
|
||||
if (mirrValuesAreAllNegatives) {
|
||||
return -1.0d;
|
||||
}
|
||||
if (mirrValuesAreAllPositives) {
|
||||
throw new EvaluationException(ErrorEval.DIV_ZERO);
|
||||
}
|
||||
|
@ -87,15 +84,11 @@ public class Mirr extends MultiOperandNumericFunction {
|
|||
double fv = 0;
|
||||
|
||||
int indexN = 0;
|
||||
for (double anIn : in) {
|
||||
if (anIn < 0) {
|
||||
pv += anIn / Math.pow(1 + financeRate + reinvestRate, indexN++);
|
||||
}
|
||||
}
|
||||
|
||||
for (double anIn : in) {
|
||||
if (anIn > 0) {
|
||||
fv += anIn * Math.pow(1 + financeRate, numOfYears - indexN++);
|
||||
fv += anIn * Math.pow(1 + reinvestRate, numOfYears - indexN++);
|
||||
} else if (anIn < 0) {
|
||||
pv += anIn / Math.pow(1 + financeRate, indexN++);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,43 +44,44 @@ final class TestMirr {
|
|||
Mirr mirr = new Mirr();
|
||||
double mirrValue;
|
||||
|
||||
double financeRate = 0.12;
|
||||
double reinvestRate = 0.1;
|
||||
double[] values = {-120000d, 39000d, 30000d, 21000d, 37000d, 46000d, reinvestRate, financeRate};
|
||||
// MIRR should not failed with these parameters
|
||||
double financeRate = 0.1;
|
||||
double reinvestRate = 0.12;
|
||||
double[] values = {-120000d, 39000d, 30000d, 21000d, 37000d, 46000d, financeRate, reinvestRate};
|
||||
mirrValue = mirr.evaluate(values);
|
||||
assertEquals(0.126094130366, mirrValue, 0.0000000001);
|
||||
|
||||
reinvestRate = 0.05;
|
||||
financeRate = 0.08;
|
||||
values = new double[]{-7500d, 3000d, 5000d, 1200d, 4000d, reinvestRate, financeRate};
|
||||
// MIRR should not failed with these parameters
|
||||
financeRate = 0.05;
|
||||
reinvestRate = 0.08;
|
||||
values = new double[]{-7500d, 3000d, 5000d, 1200d, 4000d, financeRate, reinvestRate};
|
||||
mirrValue = mirr.evaluate(values);
|
||||
assertEquals(0.18736225093, mirrValue, 0.0000000001);
|
||||
|
||||
reinvestRate = 0.065;
|
||||
financeRate = 0.1;
|
||||
values = new double[]{-10000, 3400d, 6500d, 1000d, reinvestRate, financeRate};
|
||||
// MIRR should not failed with these parameters
|
||||
financeRate = 0.065;
|
||||
reinvestRate = 0.1;
|
||||
values = new double[]{-10000, 3400d, 6500d, 1000d, financeRate, reinvestRate};
|
||||
mirrValue = mirr.evaluate(values);
|
||||
assertEquals(0.07039493966, mirrValue, 0.0000000001);
|
||||
|
||||
reinvestRate = 0.07;
|
||||
financeRate = 0.01;
|
||||
values = new double[]{-10000d, -3400d, -6500d, -1000d, reinvestRate, financeRate};
|
||||
// MIRR should not failed with these parameters
|
||||
financeRate = 0.07;
|
||||
reinvestRate = 0.01;
|
||||
values = new double[]{-10000d, -3400d, -6500d, -1000d, financeRate, reinvestRate};
|
||||
mirrValue = mirr.evaluate(values);
|
||||
assertEquals(-1, mirrValue, 0.0);
|
||||
|
||||
financeRate = 0.1;
|
||||
reinvestRate = 0.12;
|
||||
values = new double[]{-1000d, -4000d, 5000d, 2000d, financeRate, reinvestRate};
|
||||
mirrValue = mirr.evaluate(values);
|
||||
assertEquals(0.179085686035, mirrValue, 0.0000000001);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMirrErrors_expectDIV0() {
|
||||
Mirr mirr = new Mirr();
|
||||
|
||||
double reinvestRate = 0.05;
|
||||
double financeRate = 0.08;
|
||||
double[] incomes = {120000d, 39000d, 30000d, 21000d, 37000d, 46000d, reinvestRate, financeRate};
|
||||
double reinvestRate = 0.05;
|
||||
double[] incomes = {120000d, 39000d, 30000d, 21000d, 37000d, 46000d, financeRate, reinvestRate};
|
||||
|
||||
EvaluationException e = assertThrows(EvaluationException.class, () -> mirr.evaluate(incomes));
|
||||
assertEquals(ErrorEval.DIV_ZERO, e.getErrorEval());
|
||||
|
@ -117,7 +118,7 @@ final class TestMirr {
|
|||
HSSFSheet sheet = wb.getSheet("Mirr");
|
||||
HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
|
||||
int failureCount = 0;
|
||||
int[] resultRows = {9, 19, 29, 45};
|
||||
int[] resultRows = {9, 19, 29, 45, 53};
|
||||
|
||||
for (int rowNum : resultRows) {
|
||||
HSSFRow row = sheet.getRow(rowNum);
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue