From 4f7bef34f6b541c93f960f926405ede4d05da79c Mon Sep 17 00:00:00 2001 From: Josh Micich Date: Wed, 10 Sep 2008 21:21:28 +0000 Subject: [PATCH] Refactored hierarchy of MultiOperandNumericFunction. Fixed error value handling. Enabled error value check in TestFormulasFromSpreadsheet git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@693990 13f79535-47bb-0310-9956-ffa450edef68 --- .../record/formula/eval/FunctionEval.java | 61 ++- .../formula/functions/AggregateFunction.java | 120 ++++++ .../hssf/record/formula/functions/Avedev.java | 76 ---- .../record/formula/functions/Average.java | 76 ---- .../hssf/record/formula/functions/Devsq.java | 77 ---- .../hssf/record/formula/functions/Large.java | 81 ---- .../hssf/record/formula/functions/Max.java | 68 ---- .../hssf/record/formula/functions/Maxa.java | 53 +-- .../hssf/record/formula/functions/Median.java | 77 ---- .../hssf/record/formula/functions/Min.java | 68 ---- .../hssf/record/formula/functions/Mina.java | 53 +-- .../hssf/record/formula/functions/Mode.java | 62 ++- .../MultiOperandNumericFunction.java | 373 ++++++++---------- .../record/formula/functions/Product.java | 68 ---- .../hssf/record/formula/functions/Small.java | 81 ---- .../hssf/record/formula/functions/Stdev.java | 76 ---- .../hssf/record/formula/functions/Sum.java | 68 ---- .../hssf/record/formula/functions/Sumsq.java | 70 ---- .../eval/TestFormulasFromSpreadsheet.java | 18 +- .../record/formula/functions/TestAverage.java | 53 ++- 20 files changed, 401 insertions(+), 1278 deletions(-) create mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/AggregateFunction.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Avedev.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Average.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Devsq.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Large.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Max.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Median.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Min.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Product.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Small.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Stdev.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Sum.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Sumsq.java diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java index 01f363fdd..e78ab5f8e 100644 --- a/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java +++ b/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java @@ -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 8, 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; import java.util.HashMap; @@ -81,15 +78,15 @@ public abstract class FunctionEval implements OperationEval { retval[1] = new If(); // IF retval[2] = new IsNa(); // ISNA retval[3] = new IsError(); // ISERROR - retval[4] = new Sum(); // SUM - retval[5] = new Average(); // AVERAGE - retval[6] = new Min(); // MIN - retval[7] = new Max(); // MAX + retval[4] = AggregateFunction.SUM; + retval[5] = AggregateFunction.AVERAGE; + retval[6] = AggregateFunction.MIN; + retval[7] = AggregateFunction.MAX; retval[8] = new Row(); // ROW retval[9] = new Column(); // COLUMN retval[10] = new Na(); // NA retval[11] = new Npv(); // NPV - retval[12] = new Stdev(); // STDEV + retval[12] = AggregateFunction.STDEV; retval[13] = NumericFunction.DOLLAR; retval[14] = new Fixed(); // FIXED retval[15] = NumericFunction.SIN; @@ -255,7 +252,7 @@ public abstract class FunctionEval implements OperationEval { retval[180] = new NotImplementedFunction(); // RESTART retval[181] = new Help(); // HELP retval[182] = new NotImplementedFunction(); // GETBAR - retval[183] = new Product(); // PRODUCT + retval[183] = AggregateFunction.PRODUCT; retval[184] = NumericFunction.FACT; retval[185] = new NotImplementedFunction(); // GETCELL retval[186] = new NotImplementedFunction(); // GETWORKSPACE @@ -291,7 +288,7 @@ public abstract class FunctionEval implements OperationEval { retval[220] = new Days360(); // DAYS360 retval[221] = new Today(); // TODAY retval[222] = new Vdb(); // VDB - retval[227] = new Median(); // MEDIAN + retval[227] = AggregateFunction.MEDIAN; retval[228] = new Sumproduct(); // SUMPRODUCT retval[229] = NumericFunction.SINH; retval[230] = NumericFunction.COSH; @@ -331,7 +328,7 @@ public abstract class FunctionEval implements OperationEval { retval[266] = new NotImplementedFunction(); // PRESSTOOL retval[267] = new NotImplementedFunction(); // REGISTERID retval[268] = new NotImplementedFunction(); // GETWORKBOOK - retval[269] = new Avedev(); // AVEDEV + retval[269] = AggregateFunction.AVEDEV; retval[270] = new Betadist(); // BETADIST retval[271] = new Gammaln(); // GAMMALN retval[272] = new Betainv(); // BETAINV @@ -380,15 +377,15 @@ public abstract class FunctionEval implements OperationEval { retval[315] = new Slope(); // SLOPE retval[316] = new Ttest(); // TTEST retval[317] = new Prob(); // PROB - retval[318] = new Devsq(); // DEVSQ + retval[318] = AggregateFunction.DEVSQ; retval[319] = new Geomean(); // GEOMEAN retval[320] = new Harmean(); // HARMEAN - retval[321] = new Sumsq(); // SUMSQ + retval[321] = AggregateFunction.SUMSQ; retval[322] = new Kurt(); // KURT retval[323] = new Skew(); // SKEW retval[324] = new Ztest(); // ZTEST - retval[325] = new Large(); // LARGE - retval[326] = new Small(); // SMALL + retval[325] = AggregateFunction.LARGE; + retval[326] = AggregateFunction.SMALL; retval[327] = new Quartile(); // QUARTILE retval[328] = new Percentile(); // PERCENTILE retval[329] = new Percentrank(); // PERCENTRANK diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/AggregateFunction.java b/src/java/org/apache/poi/hssf/record/formula/functions/AggregateFunction.java new file mode 100644 index 000000000..be0b1e44c --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/AggregateFunction.java @@ -0,0 +1,120 @@ +/* ==================================================================== + 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.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.EvaluationException; +import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public abstract class AggregateFunction extends MultiOperandNumericFunction { + private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = + new ValueEvalToNumericXlator((short) ( + ValueEvalToNumericXlator.BOOL_IS_PARSED + | ValueEvalToNumericXlator.STRING_IS_PARSED + )); + + protected final ValueEvalToNumericXlator getXlator() { + return DEFAULT_NUM_XLATOR; + } + + + /* ---------------------------------------------------------------------- */ + + public static final Function AVEDEV = new AggregateFunction() { + protected double evaluate(double[] values) { + return StatsLib.avedev(values); + } + }; + public static final Function AVERAGE = new AggregateFunction() { + protected double evaluate(double[] values) throws EvaluationException { + if (values.length < 1) { + throw new EvaluationException(ErrorEval.DIV_ZERO); + } + return MathX.average(values); + } + }; + public static final Function DEVSQ = new AggregateFunction() { + protected double evaluate(double[] values) { + return StatsLib.devsq(values); + } + }; + public static final Function LARGE = new AggregateFunction() { + protected double evaluate(double[] ops) throws EvaluationException { + if (ops.length < 2) { + throw new EvaluationException(ErrorEval.NUM_ERROR); + } + double[] values = new double[ops.length-1]; + int k = (int) ops[ops.length-1]; + System.arraycopy(ops, 0, values, 0, values.length); + return StatsLib.kthLargest(values, k); + } + }; + public static final Function MAX = new AggregateFunction() { + protected double evaluate(double[] values) { + return values.length > 0 ? MathX.max(values) : 0; + } + }; + public static final Function MEDIAN = new AggregateFunction() { + protected double evaluate(double[] values) { + return StatsLib.median(values); + } + }; + public static final Function MIN = new AggregateFunction() { + protected double evaluate(double[] values) { + return values.length > 0 ? MathX.min(values) : 0; + } + }; + public static final Function PRODUCT = new AggregateFunction() { + protected double evaluate(double[] values) { + return MathX.product(values); + } + }; + public static final Function SMALL = new AggregateFunction() { + protected double evaluate(double[] ops) throws EvaluationException { + if (ops.length < 2) { + throw new EvaluationException(ErrorEval.NUM_ERROR); + } + double[] values = new double[ops.length-1]; + int k = (int) ops[ops.length-1]; + System.arraycopy(ops, 0, values, 0, values.length); + return StatsLib.kthSmallest(values, k); + } + }; + public static final Function STDEV = new AggregateFunction() { + protected double evaluate(double[] values) throws EvaluationException { + if (values.length < 1) { + throw new EvaluationException(ErrorEval.DIV_ZERO); + } + return StatsLib.stdev(values); + } + }; + public static final Function SUM = new AggregateFunction() { + protected double evaluate(double[] values) { + return MathX.sum(values); + } + }; + public static final Function SUMSQ = new AggregateFunction() { + protected double evaluate(double[] values) { + return MathX.sumsq(values); + } + }; +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Avedev.java b/src/java/org/apache/poi/hssf/record/formula/functions/Avedev.java deleted file mode 100644 index bf888b97d..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Avedev.java +++ /dev/null @@ -1,76 +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.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.ValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Avedev extends MultiOperandNumericFunction { - - private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = - new ValueEvalToNumericXlator((short) ( - 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 - )); - - /** - * 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; - } - - - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - double[] values = getNumberArray(operands, srcCellRow, srcCellCol); - if (values == null) { - retval = ErrorEval.VALUE_INVALID; - } - else { - double d = StatsLib.avedev(values); - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - - return retval; - } -} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Average.java b/src/java/org/apache/poi/hssf/record/formula/functions/Average.java deleted file mode 100644 index 404304071..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Average.java +++ /dev/null @@ -1,76 +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.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.ValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Average extends MultiOperandNumericFunction { - - private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = - new ValueEvalToNumericXlator((short) ( - 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 - )); - - /** - * 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; - } - - - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - double[] values = getNumberArray(operands, srcCellRow, srcCellCol); - if (values == null) { - retval = ErrorEval.VALUE_INVALID; - } - else { - double d = MathX.average(values); - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - - return retval; - } -} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Devsq.java b/src/java/org/apache/poi/hssf/record/formula/functions/Devsq.java deleted file mode 100644 index a198ff839..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Devsq.java +++ /dev/null @@ -1,77 +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.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.ValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Devsq 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 - )); - - /** - * 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; - } - - - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - double[] values = getNumberArray(operands, srcCellRow, srcCellCol); - if (values == null) { - retval = ErrorEval.VALUE_INVALID; - } - else { - double d = StatsLib.devsq(values); - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - - return retval; - } -} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Large.java b/src/java/org/apache/poi/hssf/record/formula/functions/Large.java deleted file mode 100644 index 3b9aed976..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Large.java +++ /dev/null @@ -1,81 +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.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.ValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Large 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; - } - - - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - double[] ops = getNumberArray(operands, srcCellRow, srcCellCol); - if (ops == null || ops.length < 2) { - retval = ErrorEval.VALUE_INVALID; - } - else { - double[] values = new double[ops.length-1]; - int k = (int) ops[ops.length-1]; - System.arraycopy(ops, 0, values, 0, values.length); - double d = StatsLib.kthLargest(values, k); - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - - return retval; - } -} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Max.java b/src/java/org/apache/poi/hssf/record/formula/functions/Max.java deleted file mode 100644 index d5b397149..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Max.java +++ /dev/null @@ -1,68 +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.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.ValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Max extends MultiOperandNumericFunction { - private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = - new ValueEvalToNumericXlator((short) ( - 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 - )); - - protected ValueEvalToNumericXlator getXlator() { - return DEFAULT_NUM_XLATOR; - } - - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - double[] values = getNumberArray(operands, srcCellRow, srcCellCol); - if (values == null) { - retval = ErrorEval.VALUE_INVALID; - } - else { - double d = values.length > 0 ? MathX.max(values) : 0; - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - - return retval; - } -} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Maxa.java b/src/java/org/apache/poi/hssf/record/formula/functions/Maxa.java index e25db7b74..9d7011f04 100644 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Maxa.java +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Maxa.java @@ -1,26 +1,22 @@ -/* -* 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.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.ValueEval; import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; /** @@ -46,21 +42,8 @@ public final class Maxa extends MultiOperandNumericFunction { protected ValueEvalToNumericXlator getXlator() { return DEFAULT_NUM_XLATOR; } - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - double[] values = getNumberArray(operands, srcCellRow, srcCellCol); - if (values == null) { - retval = ErrorEval.VALUE_INVALID; - } - else { - double d = values.length > 0 ? MathX.max(values) : 0; - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - - return retval; + public double evaluate(double[] values) { + return values.length > 0 ? MathX.max(values) : 0; } } diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Median.java b/src/java/org/apache/poi/hssf/record/formula/functions/Median.java deleted file mode 100644 index 57a18b331..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Median.java +++ /dev/null @@ -1,77 +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.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.ValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Median 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; - } - - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - double[] values = getNumberArray(operands, srcCellRow, srcCellCol); - if (values == null) { - retval = ErrorEval.VALUE_INVALID; - } - else { - double d = StatsLib.median(values); - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - - return retval; - } -} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Min.java b/src/java/org/apache/poi/hssf/record/formula/functions/Min.java deleted file mode 100644 index 8cd896783..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Min.java +++ /dev/null @@ -1,68 +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.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.ValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Min extends MultiOperandNumericFunction { - private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = - new ValueEvalToNumericXlator((short) ( - 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 - )); - - protected ValueEvalToNumericXlator getXlator() { - return DEFAULT_NUM_XLATOR; - } - - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - double[] values = getNumberArray(operands, srcCellRow, srcCellCol); - if (values == null) { - retval = ErrorEval.VALUE_INVALID; - } - else { - double d = values.length > 0 ? MathX.min(values) : 0; - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - - return retval; - } -} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Mina.java b/src/java/org/apache/poi/hssf/record/formula/functions/Mina.java index 21ba47b56..bbc7da824 100644 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Mina.java +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Mina.java @@ -1,26 +1,22 @@ -/* -* 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.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.ValueEval; import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; /** @@ -47,20 +43,7 @@ public class Mina extends MultiOperandNumericFunction { return DEFAULT_NUM_XLATOR; } - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - double[] values = getNumberArray(operands, srcCellRow, srcCellCol); - if (values == null) { - retval = ErrorEval.VALUE_INVALID; - } - else { - double d = values.length > 0 ? MathX.min(values) : 0; - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - - return retval; + public double evaluate(double[] values) { + return values.length > 0 ? MathX.min(values) : 0; } } diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Mode.java b/src/java/org/apache/poi/hssf/record/formula/functions/Mode.java index 724b6e654..940b9f40e 100644 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Mode.java +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Mode.java @@ -1,29 +1,24 @@ -/* -* 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 - * - */ +/* ==================================================================== + 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.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.ValueEval; +import org.apache.poi.hssf.record.formula.eval.EvaluationException; import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; /** @@ -58,21 +53,12 @@ public class Mode extends MultiOperandNumericFunction { return DEFAULT_NUM_XLATOR; } - - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - double[] values = getNumberArray(operands, srcCellRow, srcCellCol); - if (values == null) { - retval = ErrorEval.VALUE_INVALID; + 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); } - else { - double d = StatsLib.mode(values); - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - - return retval; + return d; } } diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/MultiOperandNumericFunction.java b/src/java/org/apache/poi/hssf/record/formula/functions/MultiOperandNumericFunction.java index 7d07ddc1c..1337e2fe4 100644 --- a/src/java/org/apache/poi/hssf/record/formula/functions/MultiOperandNumericFunction.java +++ b/src/java/org/apache/poi/hssf/record/formula/functions/MultiOperandNumericFunction.java @@ -1,19 +1,19 @@ -/* -* 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; @@ -21,6 +21,8 @@ import org.apache.poi.hssf.record.formula.eval.AreaEval; import org.apache.poi.hssf.record.formula.eval.BlankEval; 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.Ref2DEval; import org.apache.poi.hssf.record.formula.eval.RefEval; @@ -34,203 +36,156 @@ import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; * where the order of operands does not matter */ public abstract class MultiOperandNumericFunction implements Function { - static final double[] EMPTY_DOUBLE_ARRAY = { }; - - private static class DoubleList { - private double[] _array; - private int _count; + static final double[] EMPTY_DOUBLE_ARRAY = { }; - public DoubleList() { - _array = new double[8]; - _count = 0; - } - - public double[] toArray() { - if(_count < 1) { - return EMPTY_DOUBLE_ARRAY; - } - double[] result = new double[_count]; - System.arraycopy(_array, 0, result, 0, _count); - return result; - } + private static class DoubleList { + private double[] _array; + private int _count; - public void add(double[] values) { - int addLen = values.length; - ensureCapacity(_count + addLen); - System.arraycopy(values, 0, _array, _count, addLen); - _count += addLen; - } + public DoubleList() { + _array = new double[8]; + _count = 0; + } - private void ensureCapacity(int reqSize) { - if(reqSize > _array.length) { - int newSize = reqSize * 3 / 2; // grow with 50% extra - double[] newArr = new double[newSize]; - System.arraycopy(_array, 0, newArr, 0, _count); - _array = newArr; - } - } + public double[] toArray() { + if(_count < 1) { + return EMPTY_DOUBLE_ARRAY; + } + double[] result = new double[_count]; + System.arraycopy(_array, 0, result, 0, _count); + return result; + } - public void add(double value) { - ensureCapacity(_count + 1); - _array[_count] = value; - _count++; - } - } - - private static final int DEFAULT_MAX_NUM_OPERANDS = 30; + private void ensureCapacity(int reqSize) { + if(reqSize > _array.length) { + int newSize = reqSize * 3 / 2; // grow with 50% extra + double[] newArr = new double[newSize]; + System.arraycopy(_array, 0, newArr, 0, _count); + _array = newArr; + } + } - protected abstract ValueEvalToNumericXlator getXlator(); - - /** - * Maximum number of operands accepted by this function. - * Subclasses may override to change default value. - */ - protected int getMaxNumOperands() { - return DEFAULT_MAX_NUM_OPERANDS; - } - - /** - * Returns a double array that contains values for the numeric cells - * from among the list of operands. Blanks and Blank equivalent cells - * are ignored. Error operands or cells containing operands of type - * that are considered invalid and would result in #VALUE! error in - * excel cause this function to return null. - * - * @param operands - * @param srcRow - * @param srcCol - */ - protected double[] getNumberArray(Eval[] operands, int srcRow, short srcCol) { - if (operands.length > getMaxNumOperands()) { - return null; - } - DoubleList retval = new DoubleList(); - - for (int i=0, iSize=operands.length; ifalse if any sub-array is missing, or is of different length - */ - protected static final boolean areSubArraysConsistent(double[][] values) { - - if (values == null || values.length < 1) { - // TODO this doesn't seem right. Fix or add comment. - return true; - } - - if (values[0] == null) { - return false; - } - int outerMax = values.length; - int innerMax = values[0].length; - for (int i=1; inull. + * + * @return never null + */ + protected final double[] getNumberArray(Eval[] operands) throws EvaluationException { + if (operands.length > getMaxNumOperands()) { + throw EvaluationException.invalidValue(); + } + DoubleList retval = new DoubleList(); + + for (int i=0, iSize=operands.length; i 0 ? MathX.sum(values) : 0; - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - - return retval; - } -} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Sumsq.java b/src/java/org/apache/poi/hssf/record/formula/functions/Sumsq.java deleted file mode 100644 index b74b4161a..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Sumsq.java +++ /dev/null @@ -1,70 +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.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.ValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Sumsq extends MultiOperandNumericFunction { - private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = - new ValueEvalToNumericXlator((short) ( - 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.REF_BLANK_IS_PARSED - //| ValueEvalToNumericXlator.BLANK_IS_PARSED - )); - - protected ValueEvalToNumericXlator getXlator() { - return DEFAULT_NUM_XLATOR; - } - - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - double[] values = getNumberArray(operands, srcCellRow, srcCellCol); - if (values == null) { - retval = ErrorEval.VALUE_INVALID; - } - else { - double d = MathX.sumsq(values); - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - - return retval; - } -} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulasFromSpreadsheet.java b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulasFromSpreadsheet.java index 10e5cec64..af07b1d43 100644 --- a/src/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulasFromSpreadsheet.java +++ b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulasFromSpreadsheet.java @@ -112,15 +112,6 @@ public final class TestFormulasFromSpreadsheet extends TestCase { throw new AssertionFailedError(msg + " - actual value was null"); } - if (expected.getCellType() == HSSFCell.CELL_TYPE_STRING) { - String value = expected.getRichStringCellValue().getString(); - if (value.startsWith("#")) { - // TODO - this code never called - expected.setCellType(HSSFCell.CELL_TYPE_ERROR); - // expected.setCellErrorValue(...?); - } - } - switch (expected.getCellType()) { case HSSFCell.CELL_TYPE_BLANK: assertEquals(msg, HSSFCell.CELL_TYPE_BLANK, actual.getCellType()); @@ -131,18 +122,13 @@ public final class TestFormulasFromSpreadsheet extends TestCase { break; case HSSFCell.CELL_TYPE_ERROR: assertEquals(msg, HSSFCell.CELL_TYPE_ERROR, actual.getCellType()); - if(false) { // TODO: fix ~45 functions which are currently returning incorrect error values - assertEquals(msg, expected.getErrorCellValue(), actual.getErrorValue()); - } + assertEquals(msg, ErrorEval.getText(expected.getErrorCellValue()), ErrorEval.getText(actual.getErrorValue())); break; case HSSFCell.CELL_TYPE_FORMULA: // will never be used, since we will call method after formula evaluation throw new AssertionFailedError("Cannot expect formula as result of formula evaluation: " + msg); case HSSFCell.CELL_TYPE_NUMERIC: assertEquals(msg, HSSFCell.CELL_TYPE_NUMERIC, actual.getCellType()); TestMathX.assertEquals(msg, expected.getNumericCellValue(), actual.getNumberValue(), TestMathX.POS_ZERO, TestMathX.DIFF_TOLERANCE_FACTOR); -// double delta = Math.abs(expected.getNumericCellValue()-actual.getNumberValue()); -// double pctExpected = Math.abs(0.00001*expected.getNumericCellValue()); -// assertTrue(msg, delta <= pctExpected); break; case HSSFCell.CELL_TYPE_STRING: assertEquals(msg, HSSFCell.CELL_TYPE_STRING, actual.getCellType()); @@ -152,7 +138,7 @@ public final class TestFormulasFromSpreadsheet extends TestCase { } - protected void setUp() throws Exception { + protected void setUp() { if (workbook == null) { workbook = HSSFTestDataSamples.openSampleWorkbook(SS.FILENAME); sheet = workbook.getSheetAt( 0 ); diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestAverage.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestAverage.java index 4f0e5fff2..727f6b764 100755 --- a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestAverage.java +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestAverage.java @@ -27,14 +27,13 @@ import org.apache.poi.hssf.record.formula.eval.NumberEval; import org.apache.poi.hssf.record.formula.eval.ValueEval; /** * Tests for Excel function AVERAGE() - * + * * @author Josh Micich */ public final class TestAverage extends TestCase { - private static Eval invokeAverage(Eval[] args) { - return new Average().evaluate(args, -1, (short)-1); + return AggregateFunction.AVERAGE.evaluate(args, -1, (short)-1); } private void confirmAverage(Eval[] args, double expected) { @@ -48,56 +47,56 @@ public final class TestAverage extends TestCase { assertEquals(ErrorEval.class, result.getClass()); assertEquals(expectedError.getErrorCode(), ((ErrorEval)result).getErrorCode()); } - + public void testBasic() { - + ValueEval[] values = { - new NumberEval(1), - new NumberEval(2), - new NumberEval(3), - new NumberEval(4), + new NumberEval(1), + new NumberEval(2), + new NumberEval(3), + new NumberEval(4), }; - + confirmAverage(values, 2.5); - + values = new ValueEval[] { - new NumberEval(1), + new NumberEval(1), new NumberEval(2), BlankEval.INSTANCE, - new NumberEval(3), + new NumberEval(3), BlankEval.INSTANCE, - new NumberEval(4), + new NumberEval(4), BlankEval.INSTANCE, }; - + confirmAverage(values, 2.5); } - + /** * Valid cases where values are not pure numbers */ public void testUnusualArgs() { ValueEval[] values = { - new NumberEval(1), - new NumberEval(2), - BoolEval.TRUE, - BoolEval.FALSE, + new NumberEval(1), + new NumberEval(2), + BoolEval.TRUE, + BoolEval.FALSE, }; - + confirmAverage(values, 1.0); - + } // currently disabled because MultiOperandNumericFunction.getNumberArray(Eval[], int, short) // does not handle error values properly yet public void XtestErrors() { ValueEval[] values = { - new NumberEval(1), - ErrorEval.NAME_INVALID, - new NumberEval(3), - ErrorEval.DIV_ZERO, + new NumberEval(1), + ErrorEval.NAME_INVALID, + new NumberEval(3), + ErrorEval.DIV_ZERO, }; confirmAverage(values, ErrorEval.NAME_INVALID); - + } }