mirror of https://github.com/apache/poi.git
Refactored finance functions.
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@694050 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
562360b308
commit
4135c76ee5
|
@ -129,10 +129,10 @@ public abstract class FunctionEval implements OperationEval {
|
|||
retval[52] = new Growth(); // GROWTH
|
||||
retval[53] = new Goto(); // GOTO
|
||||
retval[54] = new Halt(); // HALT
|
||||
retval[56] = new Pv(); // PV
|
||||
retval[57] = new Fv(); // FV
|
||||
retval[58] = new Nper(); // NPER
|
||||
retval[59] = new Pmt(); // PMT
|
||||
retval[56] = FinanceFunction.PV;
|
||||
retval[57] = FinanceFunction.FV;
|
||||
retval[58] = FinanceFunction.NPER;
|
||||
retval[59] = FinanceFunction.PMT;
|
||||
retval[60] = new Rate(); // RATE
|
||||
retval[61] = new Mirr(); // MIRR
|
||||
retval[62] = new Irr(); // IRR
|
||||
|
|
|
@ -1,23 +1,20 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/*
|
||||
* Created on May 14, 2005
|
||||
*
|
||||
*/
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.hssf.record.formula.eval;
|
||||
|
||||
/**
|
||||
|
@ -30,11 +27,7 @@ public final class ValueEvalToNumericXlator {
|
|||
public static final int BOOL_IS_PARSED = 0x0002;
|
||||
public static final int BLANK_IS_PARSED = 0x0004; // => blanks are not ignored, converted to 0
|
||||
|
||||
public static final int REF_STRING_IS_PARSED = 0x0008;
|
||||
public static final int REF_BOOL_IS_PARSED = 0x0010;
|
||||
public static final int REF_BLANK_IS_PARSED = 0x0020;
|
||||
|
||||
public static final int STRING_IS_INVALID_VALUE = 0x0800;
|
||||
public static final int REF_BOOL_IS_PARSED = 0x0008;
|
||||
|
||||
private final int flags;
|
||||
|
||||
|
@ -68,11 +61,11 @@ public final class ValueEvalToNumericXlator {
|
|||
if (eval instanceof BoolEval) {
|
||||
return ((flags & BOOL_IS_PARSED) > 0)
|
||||
? (NumericValueEval) eval
|
||||
: xlateBlankEval(BLANK_IS_PARSED);
|
||||
: xlateBlankEval();
|
||||
}
|
||||
|
||||
if (eval instanceof StringEval) {
|
||||
return xlateStringEval((StringEval) eval); // TODO: recursive call needed
|
||||
return xlateStringEval((StringEval) eval);
|
||||
}
|
||||
|
||||
if (eval instanceof RefEval) {
|
||||
|
@ -84,7 +77,7 @@ public final class ValueEvalToNumericXlator {
|
|||
}
|
||||
|
||||
if (eval instanceof BlankEval) {
|
||||
return xlateBlankEval(BLANK_IS_PARSED);
|
||||
return xlateBlankEval();
|
||||
}
|
||||
|
||||
// probably AreaEval? then not acceptable.
|
||||
|
@ -97,8 +90,8 @@ public final class ValueEvalToNumericXlator {
|
|||
* valued numbereval is returned, else BlankEval.INSTANCE
|
||||
* is returned.
|
||||
*/
|
||||
private ValueEval xlateBlankEval(int flag) {
|
||||
return ((flags & flag) > 0)
|
||||
private ValueEval xlateBlankEval() {
|
||||
return ((flags & BLANK_IS_PARSED) > 0)
|
||||
? (ValueEval) NumberEval.ZERO
|
||||
: BlankEval.INSTANCE;
|
||||
}
|
||||
|
@ -122,7 +115,8 @@ public final class ValueEvalToNumericXlator {
|
|||
}
|
||||
|
||||
if (eval instanceof StringEval) {
|
||||
return xlateRefStringEval((StringEval) eval);
|
||||
// all ref strings are blanks
|
||||
return BlankEval.INSTANCE;
|
||||
}
|
||||
|
||||
if (eval instanceof ErrorEval) {
|
||||
|
@ -130,7 +124,7 @@ public final class ValueEvalToNumericXlator {
|
|||
}
|
||||
|
||||
if (eval instanceof BlankEval) {
|
||||
return xlateBlankEval(REF_BLANK_IS_PARSED);
|
||||
return xlateBlankEval();
|
||||
}
|
||||
|
||||
throw new RuntimeException("Invalid ValueEval type passed for conversion: ("
|
||||
|
@ -151,29 +145,7 @@ public final class ValueEvalToNumericXlator {
|
|||
}
|
||||
return new NumberEval(d.doubleValue());
|
||||
}
|
||||
// strings are errors?
|
||||
if ((flags & STRING_IS_INVALID_VALUE) > 0) {
|
||||
return ErrorEval.VALUE_INVALID;
|
||||
}
|
||||
|
||||
// ignore strings
|
||||
return xlateBlankEval(BLANK_IS_PARSED);
|
||||
}
|
||||
|
||||
/**
|
||||
* uses the relevant flags to decode the StringEval
|
||||
* @param eval
|
||||
*/
|
||||
private ValueEval xlateRefStringEval(StringEval sve) {
|
||||
if ((flags & REF_STRING_IS_PARSED) > 0) {
|
||||
String s = sve.getStringValue();
|
||||
Double d = OperandResolver.parseDouble(s);
|
||||
if(d == null) {
|
||||
return ErrorEval.VALUE_INVALID;
|
||||
}
|
||||
return new NumberEval(d.doubleValue());
|
||||
}
|
||||
// strings are blanks
|
||||
return BlankEval.INSTANCE;
|
||||
// else strings are errors?
|
||||
return ErrorEval.VALUE_INVALID;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hssf.record.formula.functions;
|
|||
|
||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.EvaluationException;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
|
||||
|
||||
/**
|
||||
|
@ -32,8 +33,8 @@ public abstract class AggregateFunction extends MultiOperandNumericFunction {
|
|||
| ValueEvalToNumericXlator.STRING_IS_PARSED
|
||||
));
|
||||
|
||||
protected final ValueEvalToNumericXlator getXlator() {
|
||||
return DEFAULT_NUM_XLATOR;
|
||||
protected ValueEval attemptXlateToNumeric(ValueEval ve) {
|
||||
return DEFAULT_NUM_XLATOR.attemptXlateToNumeric(ve);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,103 +1,77 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.Eval;
|
||||
import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.eval.EvaluationException;
|
||||
|
||||
/**
|
||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
||||
* Super class for all Evals for financial function evaluation.
|
||||
*
|
||||
*
|
||||
*/
|
||||
public abstract class FinanceFunction implements Function {
|
||||
private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
|
||||
new ValueEvalToNumericXlator((short) (0
|
||||
| ValueEvalToNumericXlator.BOOL_IS_PARSED
|
||||
| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
|
||||
| ValueEvalToNumericXlator.STRING_IS_PARSED
|
||||
| ValueEvalToNumericXlator.REF_STRING_IS_PARSED
|
||||
| ValueEvalToNumericXlator.BLANK_IS_PARSED
|
||||
| ValueEvalToNumericXlator.REF_BLANK_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE
|
||||
//| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE
|
||||
));
|
||||
|
||||
/**
|
||||
* this is the default impl of the factory(ish) method getXlator.
|
||||
* Subclasses can override this method
|
||||
* if they desire to return a different ValueEvalToNumericXlator instance
|
||||
* than the default.
|
||||
*/
|
||||
protected final ValueEvalToNumericXlator getXlator() {
|
||||
return DEFAULT_NUM_XLATOR;
|
||||
}
|
||||
|
||||
protected final ValueEval singleOperandNumericAsBoolean(Eval eval, int srcRow, short srcCol) {
|
||||
ValueEval retval = null;
|
||||
retval = singleOperandEvaluate(eval, srcRow, srcCol);
|
||||
if (retval instanceof NumericValueEval) {
|
||||
NumericValueEval nve = (NumericValueEval) retval;
|
||||
retval = (nve.getNumberValue() == 0)
|
||||
? BoolEval.FALSE
|
||||
: BoolEval.TRUE;
|
||||
}
|
||||
else {
|
||||
retval = ErrorEval.VALUE_INVALID;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
protected final ValueEval singleOperandEvaluate(Eval eval, int srcRow, short srcCol) {
|
||||
public abstract class FinanceFunction extends NumericFunction.MultiArg {
|
||||
|
||||
if (eval instanceof AreaEval) {
|
||||
AreaEval ae = (AreaEval) eval;
|
||||
if (ae.contains(srcRow, srcCol)) { // circular ref!
|
||||
return ErrorEval.CIRCULAR_REF_ERROR;
|
||||
}
|
||||
if (ae.isRow()) {
|
||||
if (ae.isColumn()) {
|
||||
return ae.getRelativeValue(0, 0);
|
||||
}
|
||||
if (ae.containsColumn(srcCol)) {
|
||||
ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol);
|
||||
ve = getXlator().attemptXlateToNumeric(ve);
|
||||
return getXlator().attemptXlateToNumeric(ve);
|
||||
}
|
||||
return ErrorEval.VALUE_INVALID;
|
||||
}
|
||||
if (ae.isColumn()) {
|
||||
if (ae.containsRow(srcRow)) {
|
||||
ValueEval ve = ae.getValueAt(srcRow, ae.getFirstColumn());
|
||||
return getXlator().attemptXlateToNumeric(ve);
|
||||
}
|
||||
return ErrorEval.VALUE_INVALID;
|
||||
}
|
||||
return ErrorEval.VALUE_INVALID;
|
||||
}
|
||||
return getXlator().attemptXlateToNumeric((ValueEval) eval);
|
||||
}
|
||||
|
||||
protected FinanceFunction() {
|
||||
super (3, 5);
|
||||
}
|
||||
|
||||
protected double evaluate(double[] ds) throws EvaluationException {
|
||||
// All finance functions have 3 to 5 args, first 4 are numbers, last is boolean
|
||||
// default for last 2 args are 0.0 and false
|
||||
// Text boolean literals are not valid for the last arg
|
||||
|
||||
double arg3 = 0.0;
|
||||
double arg4 = 0.0;
|
||||
|
||||
switch(ds.length) {
|
||||
case 5:
|
||||
arg4 = ds[4];
|
||||
case 4:
|
||||
arg3 = ds[3];
|
||||
case 3:
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Wrong number of arguments");
|
||||
}
|
||||
return evaluate(ds[0], ds[1], ds[2], arg3, arg4!=0.0);
|
||||
}
|
||||
|
||||
protected abstract double evaluate(double rate, double arg1, double arg2, double arg3, boolean type) throws EvaluationException ;
|
||||
|
||||
|
||||
public static final Function FV = new FinanceFunction() {
|
||||
protected double evaluate(double rate, double arg1, double arg2, double arg3, boolean type) {
|
||||
return FinanceLib.fv(rate, arg1, arg2, arg3, type);
|
||||
}
|
||||
};
|
||||
public static final Function NPER = new FinanceFunction() {
|
||||
protected double evaluate(double rate, double arg1, double arg2, double arg3, boolean type) {
|
||||
return FinanceLib.nper(rate, arg1, arg2, arg3, type);
|
||||
}
|
||||
};
|
||||
public static final Function PMT = new FinanceFunction() {
|
||||
protected double evaluate(double rate, double arg1, double arg2, double arg3, boolean type) {
|
||||
return FinanceLib.pmt(rate, arg1, arg2, arg3, type);
|
||||
}
|
||||
};
|
||||
public static final Function PV = new FinanceFunction() {
|
||||
protected double evaluate(double rate, double arg1, double arg2, double arg3, boolean type) {
|
||||
return FinanceLib.pv(rate, arg1, arg2, arg3, type);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/*
|
||||
* Created on May 15, 2005
|
||||
*
|
||||
*/
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.Eval;
|
||||
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
|
||||
public class Fv extends FinanceFunction {
|
||||
|
||||
public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
|
||||
double rate = 0, nper = 0, pmt = 0, pv = 0, d = 0;
|
||||
boolean type = false;
|
||||
ValueEval retval = null;
|
||||
ValueEval ve = null;
|
||||
|
||||
switch (operands.length) {
|
||||
default:
|
||||
retval = ErrorEval.VALUE_INVALID;
|
||||
break;
|
||||
case 5:
|
||||
ve = singleOperandNumericAsBoolean(operands[4], srcRow, srcCol);
|
||||
if (ve instanceof ErrorEval) { retval = ErrorEval.VALUE_INVALID; break; }
|
||||
type = ((BoolEval) ve).getBooleanValue();
|
||||
case 4:
|
||||
ve = singleOperandEvaluate(operands[3], srcRow, srcCol);
|
||||
if (ve instanceof NumericValueEval) pv = ((NumericValueEval) ve).getNumberValue();
|
||||
else { retval = ErrorEval.VALUE_INVALID; break; }
|
||||
case 3:
|
||||
ve = singleOperandEvaluate(operands[1], srcRow, srcCol);
|
||||
if (ve instanceof NumericValueEval) nper = ((NumericValueEval) ve).getNumberValue();
|
||||
else { retval = ErrorEval.VALUE_INVALID; break; }
|
||||
|
||||
ve = singleOperandEvaluate(operands[2], srcRow, srcCol);
|
||||
if (ve instanceof NumericValueEval) pmt = ((NumericValueEval) ve).getNumberValue();
|
||||
else { retval = ErrorEval.VALUE_INVALID; break; }
|
||||
|
||||
ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
|
||||
if (ve instanceof NumericValueEval) rate = ((NumericValueEval) ve).getNumberValue();
|
||||
else { retval = ErrorEval.VALUE_INVALID; break; }
|
||||
}
|
||||
|
||||
if (retval == null) {
|
||||
d = FinanceLib.fv(rate, nper, pmt, pv, type);
|
||||
retval = (Double.isNaN(d))
|
||||
? (ValueEval) ErrorEval.VALUE_INVALID
|
||||
: (Double.isInfinite(d))
|
||||
? (ValueEval) ErrorEval.NUM_ERROR
|
||||
: new NumberEval(d);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
}
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
|
||||
|
||||
/**
|
||||
|
@ -29,19 +30,12 @@ public final class Maxa extends MultiOperandNumericFunction {
|
|||
ValueEvalToNumericXlator.BOOL_IS_PARSED
|
||||
| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
|
||||
| ValueEvalToNumericXlator.STRING_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.REF_STRING_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED
|
||||
| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE
|
||||
//| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE
|
||||
| ValueEvalToNumericXlator.BLANK_IS_PARSED
|
||||
| ValueEvalToNumericXlator.REF_BLANK_IS_PARSED
|
||||
));
|
||||
|
||||
protected ValueEvalToNumericXlator getXlator() {
|
||||
return DEFAULT_NUM_XLATOR;
|
||||
}
|
||||
protected ValueEval attemptXlateToNumeric(ValueEval ve) {
|
||||
return DEFAULT_NUM_XLATOR.attemptXlateToNumeric(ve);
|
||||
}
|
||||
|
||||
public double evaluate(double[] values) {
|
||||
return values.length > 0 ? MathX.max(values) : 0;
|
||||
|
|
|
@ -17,31 +17,25 @@
|
|||
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
|
||||
|
||||
/**
|
||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
||||
*
|
||||
*/
|
||||
public class Mina extends MultiOperandNumericFunction {
|
||||
public final class Mina extends MultiOperandNumericFunction {
|
||||
private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
|
||||
new ValueEvalToNumericXlator((short) (
|
||||
ValueEvalToNumericXlator.BOOL_IS_PARSED
|
||||
| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
|
||||
| ValueEvalToNumericXlator.STRING_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.REF_STRING_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED
|
||||
| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE
|
||||
//| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE
|
||||
| ValueEvalToNumericXlator.REF_BLANK_IS_PARSED
|
||||
| ValueEvalToNumericXlator.BLANK_IS_PARSED
|
||||
));
|
||||
|
||||
protected ValueEvalToNumericXlator getXlator() {
|
||||
return DEFAULT_NUM_XLATOR;
|
||||
}
|
||||
protected ValueEval attemptXlateToNumeric(ValueEval ve) {
|
||||
return DEFAULT_NUM_XLATOR.attemptXlateToNumeric(ve);
|
||||
}
|
||||
|
||||
public double evaluate(double[] values) {
|
||||
return values.length > 0 ? MathX.min(values) : 0;
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hssf.record.formula.functions;
|
|||
|
||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.EvaluationException;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
|
||||
|
||||
/**
|
||||
|
@ -26,39 +27,25 @@ import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
|
|||
*
|
||||
*/
|
||||
public class Mode extends MultiOperandNumericFunction {
|
||||
private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
|
||||
new ValueEvalToNumericXlator((short) (0
|
||||
//| ValueEvalToNumericXlator.BOOL_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.STRING_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.REF_STRING_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED
|
||||
| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE
|
||||
//| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE
|
||||
//| ValueEvalToNumericXlator.EVALUATED_REF_BLANK_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.REF_BLANK_IS_PARSED
|
||||
//| ValueEvalToNumericXlator.BLANK_IS_PARSED
|
||||
));
|
||||
|
||||
/**
|
||||
* this is the default impl for the factory method getXlator
|
||||
* of the super class NumericFunction. Subclasses can override this method
|
||||
* if they desire to return a different ValueEvalToNumericXlator instance
|
||||
* than the default.
|
||||
*/
|
||||
protected ValueEvalToNumericXlator getXlator() {
|
||||
return DEFAULT_NUM_XLATOR;
|
||||
}
|
||||
private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
|
||||
new ValueEvalToNumericXlator(0);
|
||||
|
||||
protected double evaluate(double[] values) throws EvaluationException {
|
||||
double d = StatsLib.mode(values);
|
||||
if (Double.isNaN(d)) {
|
||||
// TODO - StatsLib is returning NaN to denote 'no duplicate values'
|
||||
throw new EvaluationException(ErrorEval.NA);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
/**
|
||||
* this is the default impl for the factory method getXlator
|
||||
* of the super class NumericFunction. Subclasses can override this method
|
||||
* if they desire to return a different ValueEvalToNumericXlator instance
|
||||
* than the default.
|
||||
*/
|
||||
protected ValueEval attemptXlateToNumeric(ValueEval ve) {
|
||||
return DEFAULT_NUM_XLATOR.attemptXlateToNumeric(ve);
|
||||
}
|
||||
|
||||
protected double evaluate(double[] values) throws EvaluationException {
|
||||
double d = StatsLib.mode(values);
|
||||
if (Double.isNaN(d)) {
|
||||
// TODO - StatsLib is returning NaN to denote 'no duplicate values'
|
||||
throw new EvaluationException(ErrorEval.NA);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
|
|||
import org.apache.poi.hssf.record.formula.eval.Ref2DEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.RefEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
|
||||
|
||||
/**
|
||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
||||
|
@ -74,9 +73,6 @@ public abstract class MultiOperandNumericFunction implements Function {
|
|||
|
||||
private static final int DEFAULT_MAX_NUM_OPERANDS = 30;
|
||||
|
||||
protected abstract ValueEvalToNumericXlator getXlator();
|
||||
|
||||
|
||||
public final Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
|
||||
|
||||
double d;
|
||||
|
@ -185,7 +181,5 @@ public abstract class MultiOperandNumericFunction implements Function {
|
|||
}
|
||||
|
||||
|
||||
protected ValueEval attemptXlateToNumeric(ValueEval ve) {
|
||||
return getXlator().attemptXlateToNumeric(ve);
|
||||
}
|
||||
protected abstract ValueEval attemptXlateToNumeric(ValueEval ve);
|
||||
}
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/*
|
||||
* Created on May 15, 2005
|
||||
*
|
||||
*/
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.Eval;
|
||||
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
|
||||
public class Nper extends FinanceFunction {
|
||||
|
||||
public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
|
||||
double rate = 0, fv = 0, pmt = 0, pv = 0, d = 0;
|
||||
boolean type = false;
|
||||
ValueEval retval = null;
|
||||
ValueEval ve = null;
|
||||
|
||||
switch (operands.length) {
|
||||
default:
|
||||
retval = ErrorEval.VALUE_INVALID;
|
||||
break;
|
||||
case 5:
|
||||
ve = singleOperandNumericAsBoolean(operands[4], srcRow, srcCol);
|
||||
if (ve instanceof ErrorEval) { retval = ErrorEval.VALUE_INVALID; break; }
|
||||
type = ((BoolEval) ve).getBooleanValue();
|
||||
case 4:
|
||||
ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
|
||||
if (ve instanceof NumericValueEval) rate = ((NumericValueEval) ve).getNumberValue();
|
||||
else { retval = ErrorEval.VALUE_INVALID; break; }
|
||||
|
||||
ve = singleOperandEvaluate(operands[1], srcRow, srcCol);
|
||||
if (ve instanceof NumericValueEval) pmt = ((NumericValueEval) ve).getNumberValue();
|
||||
else { retval = ErrorEval.VALUE_INVALID; break; }
|
||||
|
||||
ve = singleOperandEvaluate(operands[2], srcRow, srcCol);
|
||||
if (ve instanceof NumericValueEval) pv = ((NumericValueEval) ve).getNumberValue();
|
||||
else { retval = ErrorEval.VALUE_INVALID; break; }
|
||||
|
||||
ve = singleOperandEvaluate(operands[3], srcRow, srcCol);
|
||||
if (ve instanceof NumericValueEval) fv = ((NumericValueEval) ve).getNumberValue();
|
||||
else { retval = ErrorEval.VALUE_INVALID; break; }
|
||||
}
|
||||
|
||||
if (retval == null) {
|
||||
d = FinanceLib.nper(rate, pmt, pv, fv, type);
|
||||
retval = (Double.isNaN(d))
|
||||
? (ValueEval) ErrorEval.VALUE_INVALID
|
||||
: (Double.isInfinite(d))
|
||||
? (ValueEval) ErrorEval.NUM_ERROR
|
||||
: new NumberEval(d);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,91 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.Eval;
|
||||
import org.apache.poi.hssf.record.formula.eval.EvaluationException;
|
||||
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
|
||||
/**
|
||||
* Implementation for the PMT() Excel function.<p/>
|
||||
*
|
||||
* <b>Syntax:</b><br/>
|
||||
* <b>PMT</b>(<b>rate</b>, <b>nper</b>, <b>pv</b>, fv, type)<p/>
|
||||
*
|
||||
* Returns the constant repayment amount required for a loan assuming a constant interest rate.<p/>
|
||||
*
|
||||
* <b>rate</b> the loan interest rate.<br/>
|
||||
* <b>nper</b> the number of loan repayments.<br/>
|
||||
* <b>pv</b> the present value of the future payments (or principle).<br/>
|
||||
* <b>fv</b> the future value (default zero) surplus cash at the end of the loan lifetime.<br/>
|
||||
* <b>type</b> whether payments are due at the beginning(1) or end(0 - default) of each payment period.<br/>
|
||||
*
|
||||
*/
|
||||
public final class Pmt extends FinanceFunction {
|
||||
|
||||
public Eval evaluate(Eval[] args, int srcRow, short srcCol) {
|
||||
|
||||
if(args.length < 3 || args.length > 5) {
|
||||
return ErrorEval.VALUE_INVALID;
|
||||
}
|
||||
|
||||
try {
|
||||
// evaluate first three (always present) args
|
||||
double rate = evalArg(args[0], srcRow, srcCol);
|
||||
double nper = evalArg(args[1], srcRow, srcCol);
|
||||
double pv = evalArg(args[2], srcRow, srcCol);
|
||||
double fv = 0;
|
||||
boolean arePaymentsAtPeriodBeginning = false;
|
||||
|
||||
switch (args.length) {
|
||||
case 5:
|
||||
ValueEval ve = singleOperandNumericAsBoolean(args[4], srcRow, srcCol);
|
||||
if (ve instanceof ErrorEval) {
|
||||
return ve;
|
||||
}
|
||||
arePaymentsAtPeriodBeginning = ((BoolEval) ve).getBooleanValue();
|
||||
case 4:
|
||||
fv = evalArg(args[3], srcRow, srcCol);
|
||||
}
|
||||
double d = FinanceLib.pmt(rate, nper, pv, fv, arePaymentsAtPeriodBeginning);
|
||||
if (Double.isNaN(d)) {
|
||||
return ErrorEval.VALUE_INVALID;
|
||||
}
|
||||
if (Double.isInfinite(d)) {
|
||||
return ErrorEval.NUM_ERROR;
|
||||
}
|
||||
return new NumberEval(d);
|
||||
} catch (EvaluationException e) {
|
||||
return e.getErrorEval();
|
||||
}
|
||||
}
|
||||
|
||||
private double evalArg(Eval arg, int srcRow, short srcCol) throws EvaluationException {
|
||||
ValueEval ve = singleOperandEvaluate(arg, srcRow, srcCol);
|
||||
if(ve instanceof ErrorEval) {
|
||||
throw new EvaluationException((ErrorEval) ve);
|
||||
}
|
||||
if (ve instanceof NumericValueEval) {
|
||||
return ((NumericValueEval) ve).getNumberValue();
|
||||
}
|
||||
throw new EvaluationException(ErrorEval.VALUE_INVALID);
|
||||
}
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/*
|
||||
* Created on May 15, 2005
|
||||
*
|
||||
*/
|
||||
package org.apache.poi.hssf.record.formula.functions;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.Eval;
|
||||
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
|
||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||
|
||||
public class Pv extends FinanceFunction {
|
||||
|
||||
public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
|
||||
double rate = 0, fv = 0, nper = 0, pmt = 0, d = 0;
|
||||
boolean type = false;
|
||||
ValueEval retval = null;
|
||||
ValueEval ve = null;
|
||||
|
||||
switch (operands.length) {
|
||||
default:
|
||||
retval = ErrorEval.VALUE_INVALID;
|
||||
break;
|
||||
case 5:
|
||||
ve = singleOperandNumericAsBoolean(operands[4], srcRow, srcCol);
|
||||
if (ve instanceof ErrorEval) { retval = ErrorEval.VALUE_INVALID; break; }
|
||||
type = ((BoolEval) ve).getBooleanValue();
|
||||
case 4:
|
||||
ve = singleOperandEvaluate(operands[3], srcRow, srcCol);
|
||||
if (ve instanceof NumericValueEval) fv = ((NumericValueEval) ve).getNumberValue();
|
||||
else { retval = ErrorEval.VALUE_INVALID; break; }
|
||||
case 3:
|
||||
ve = singleOperandEvaluate(operands[1], srcRow, srcCol);
|
||||
if (ve instanceof NumericValueEval) nper = ((NumericValueEval) ve).getNumberValue();
|
||||
else { retval = ErrorEval.VALUE_INVALID; break; }
|
||||
|
||||
ve = singleOperandEvaluate(operands[2], srcRow, srcCol);
|
||||
if (ve instanceof NumericValueEval) pmt = ((NumericValueEval) ve).getNumberValue();
|
||||
else { retval = ErrorEval.VALUE_INVALID; break; }
|
||||
|
||||
ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
|
||||
if (ve instanceof NumericValueEval) rate = ((NumericValueEval) ve).getNumberValue();
|
||||
else { retval = ErrorEval.VALUE_INVALID; break; }
|
||||
}
|
||||
|
||||
if (retval == null) {
|
||||
d = FinanceLib.pv(rate, nper, pmt, fv, type);
|
||||
retval = (Double.isNaN(d))
|
||||
? (ValueEval) ErrorEval.VALUE_INVALID
|
||||
: (Double.isInfinite(d))
|
||||
? (ValueEval) ErrorEval.NUM_ERROR
|
||||
: new NumberEval(d);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
}
|
Binary file not shown.
|
@ -36,7 +36,7 @@ public final class TestPmt extends TestCase {
|
|||
assertEquals(expected, ne.getNumberValue(), 0.00005);
|
||||
}
|
||||
private static Eval invoke(Eval[] args) {
|
||||
return new Pmt().evaluate(args, -1, (short)-1);
|
||||
return FinanceFunction.PMT.evaluate(args, -1, (short)-1);
|
||||
}
|
||||
/**
|
||||
* Invocation when not expecting an error result
|
||||
|
|
Loading…
Reference in New Issue