*/
boolean isColumn();
- /**
- * The array of values in this area. Although the area
- * maybe 1D (ie. isRow() or isColumn() returns true) or 2D
- * the returned array is 1D.
- */
- ValueEval[] getValues();
-
/**
* @return the ValueEval from within this area at the specified row and col index. Never
* <code>null</code> (possibly {@link BlankEval}). The specified indexes should be absolute
return _lastRow;
}
- public final ValueEval[] getValues() {
- // TODO - clone() - but some junits rely on not cloning at the moment
- return _values;
- }
-
public final ValueEval getValueAt(int row, int col) {
int rowOffsetIx = row - _firstRow;
int colOffsetIx = col - _firstColumn;
}
}
}
-
+ public final String toString() {
+ StringBuffer sb = new StringBuffer(64);
+ sb.append(getClass().getName()).append(" [");
+ sb.append(getStringValue());
+ sb.append("]");
+ return sb.toString();
+ }
}
-/*
-* 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.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.RefEval;
+import org.apache.poi.hssf.record.formula.eval.EvaluationException;
+import org.apache.poi.hssf.record.formula.eval.OperandResolver;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
/**
* Implementation for the Excel function INDEX<p/>
return ErrorEval.VALUE_INVALID;
}
Eval firstArg = args[0];
- if(firstArg instanceof AreaEval) {
- AreaEval reference = (AreaEval) firstArg;
+ if(!(firstArg instanceof AreaEval)) {
+
+ // else the other variation of this function takes an array as the first argument
+ // it seems like interface 'ArrayEval' does not even exist yet
- int rowIx = 0;
- int columnIx = 0;
- int areaIx = 0;
+ throw new RuntimeException("Incomplete code - cannot handle first arg of type ("
+ + firstArg.getClass().getName() + ")");
+ }
+ AreaEval reference = (AreaEval) firstArg;
+
+ int rowIx = 0;
+ int columnIx = 0;
+ int areaIx = 0;
+ try {
switch(nArgs) {
case 4:
- areaIx = convertIndexArgToZeroBase(args[3]);
+ areaIx = convertIndexArgToZeroBase(args[3], srcCellRow, srcCellCol);
throw new RuntimeException("Incomplete code" +
" - don't know how to support the 'area_num' parameter yet)");
// Excel expression might look like this "INDEX( (A1:B4, C3:D6, D2:E5 ), 1, 2, 3)
// The formula parser doesn't seem to support this yet. Not sure if the evaluator does either
case 3:
- columnIx = convertIndexArgToZeroBase(args[2]);
+ columnIx = convertIndexArgToZeroBase(args[2], srcCellRow, srcCellCol);
case 2:
- rowIx = convertIndexArgToZeroBase(args[1]);
+ rowIx = convertIndexArgToZeroBase(args[1], srcCellRow, srcCellCol);
break;
default:
// too many arguments
return ErrorEval.VALUE_INVALID;
}
-
- int nColumns = reference.getLastColumn()-reference.getFirstColumn()+1;
- int index = rowIx * nColumns + columnIx;
-
- return reference.getValues()[index];
+ return getValueFromArea(reference, rowIx, columnIx);
+ } catch (EvaluationException e) {
+ return e.getErrorEval();
}
-
- // else the other variation of this function takes an array as the first argument
- // it seems like interface 'ArrayEval' does not even exist yet
-
- throw new RuntimeException("Incomplete code - cannot handle first arg of type ("
- + firstArg.getClass().getName() + ")");
}
+ private static ValueEval getValueFromArea(AreaEval ae, int rowIx, int columnIx) throws EvaluationException {
+ int width = ae.getWidth();
+ int height = ae.getHeight();
+
+ // Slightly irregular logic for bounds checking errors
+ if (rowIx >= height || columnIx >= width) {
+ throw new EvaluationException(ErrorEval.REF_INVALID);
+ }
+ if (rowIx < 0 || columnIx < 0) {
+ throw new EvaluationException(ErrorEval.VALUE_INVALID);
+ }
+ return ae.getRelativeValue(rowIx, columnIx);
+ }
+
/**
* takes a NumberEval representing a 1-based index and returns the zero-based int value
*/
- private static int convertIndexArgToZeroBase(Eval ev) {
- NumberEval ne;
- if(ev instanceof RefEval) {
- // TODO - write junit to justify this
- RefEval re = (RefEval) ev;
- ne = (NumberEval) re.getInnerValueEval();
- } else {
- ne = (NumberEval)ev;
- }
+ private static int convertIndexArgToZeroBase(Eval arg, int srcCellRow, short srcCellCol) throws EvaluationException {
- return (int)ne.getNumberValue() - 1;
+ ValueEval ev = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
+ int oneBasedVal = OperandResolver.coerceValueToInt(ev);
+ return oneBasedVal - 1;
}
}
if (operand instanceof AreaEval) {
AreaEval ae = (AreaEval) operand;
- ValueEval[] values = ae.getValues();
DoubleList retval = new DoubleList();
- for (int j=0, jSize=values.length; j<jSize; j++) {
- /*
- * TODO: For an AreaEval, we are constructing a RefEval
- * per element.
- * For now this is a tempfix solution since this may
- * require a more generic fix at the level of
- * HSSFFormulaEvaluator where we store an array
- * of RefEvals as the "values" array.
- */
- RefEval re = new Ref2DEval(null, values[j]);
- ValueEval ve = singleOperandEvaluate(re, srcRow, srcCol);
-
- if (ve instanceof NumericValueEval) {
- NumericValueEval nve = (NumericValueEval) ve;
- retval.add(nve.getNumberValue());
- }
- else if (ve instanceof BlankEval) {
- // note - blanks are ignored, so returned array will be smaller.
- }
- else {
- return null; // indicate to calling subclass that error occurred
- }
+ int width = ae.getWidth();
+ int height = ae.getHeight();
+ for (int rrIx=0; rrIx<height; rrIx++) {
+ for (int rcIx=0; rcIx<width; rcIx++) {
+ ValueEval ve1 = ae.getRelativeValue(rrIx, rcIx);
+ /*
+ * TODO: For an AreaEval, we are constructing a RefEval
+ * per element.
+ * For now this is a tempfix solution since this may
+ * require a more generic fix at the level of
+ * HSSFFormulaEvaluator where we store an array
+ * of RefEvals as the "values" array.
+ */
+ RefEval re = new Ref2DEval(null, ve1);
+ ValueEval ve = singleOperandEvaluate(re, srcRow, srcCol);
+
+ if (ve instanceof NumericValueEval) {
+ NumericValueEval nve = (NumericValueEval) ve;
+ retval.add(nve.getNumberValue());
+ }
+ else if (ve instanceof BlankEval) {
+ // note - blanks are ignored, so returned array will be smaller.
+ }
+ else {
+ return null; // indicate to calling subclass that error occurred
+ }
+ }
}
return retval.toArray();
}
-/*
-* 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;
+
/**
* Implementation of Excel function SUMX2MY2()<p/>
*
*/
public final class Sumx2my2 extends XYNumericFunction {
- protected double evaluate(double[] xArray, double[] yArray) {
- return MathX.sumx2my2(xArray, yArray);
- }
+ private static final Accumulator XSquaredMinusYSquaredAccumulator = new Accumulator() {
+ public double accumulate(double x, double y) {
+ return x * x - y * y;
+ }
+ };
+
+ protected Accumulator createAccumulator() {
+ return XSquaredMinusYSquaredAccumulator;
+ }
}
-/*
-* 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;
+
/**
* Implementation of Excel function SUMX2PY2()<p/>
*
*/
public final class Sumx2py2 extends XYNumericFunction {
- protected double evaluate(double[] xArray, double[] yArray) {
- return MathX.sumx2py2(xArray, yArray);
- }
+ private static final Accumulator XSquaredPlusYSquaredAccumulator = new Accumulator() {
+ public double accumulate(double x, double y) {
+ return x * x + y * y;
+ }
+ };
+
+ protected Accumulator createAccumulator() {
+ return XSquaredPlusYSquaredAccumulator;
+ }
}
-/*
-* 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;
*/
public final class Sumxmy2 extends XYNumericFunction {
- protected double evaluate(double[] xArray, double[] yArray) {
- return MathX.sumxmy2(xArray, yArray);
- }
+ private static final Accumulator XMinusYSquaredAccumulator = new Accumulator() {
+ public double accumulate(double x, double y) {
+ double xmy = x - y;
+ return xmy * xmy;
+ }
+ };
+
+ protected Accumulator createAccumulator() {
+ return XMinusYSquaredAccumulator;
+ }
}
-/*
-* 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.NumberEval;
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.functions.LookupUtils.ValueVector;
/**
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- *
+ *
*/
public abstract class XYNumericFunction implements Function {
- protected static final int X = 0;
- protected static final int Y = 1;
-
- protected static final class DoubleArrayPair {
- private final double[] _xArray;
- private final double[] _yArray;
+ private static abstract class ValueArray implements ValueVector {
+ private final int _size;
+ protected ValueArray(int size) {
+ _size = size;
+ }
+ public ValueEval getItem(int index) {
+ if (index < 0 || index > _size) {
+ throw new IllegalArgumentException("Specified index " + index
+ + " is outside range (0.." + (_size - 1) + ")");
+ }
+ return getItemInternal(index);
+ }
+ protected abstract ValueEval getItemInternal(int index);
+ public final int getSize() {
+ return _size;
+ }
+ }
- public DoubleArrayPair(double[] xArray, double[] yArray) {
- _xArray = xArray;
- _yArray = yArray;
+ private static final class SingleCellValueArray extends ValueArray {
+ private final ValueEval _value;
+ public SingleCellValueArray(ValueEval value) {
+ super(1);
+ _value = value;
}
- public double[] getXArray() {
- return _xArray;
+ protected ValueEval getItemInternal(int index) {
+ return _value;
+ }
+ }
+
+ private static final class RefValueArray extends ValueArray {
+ private final RefEval _ref;
+ public RefValueArray(RefEval ref) {
+ super(1);
+ _ref = ref;
}
- public double[] getYArray() {
- return _yArray;
+ protected ValueEval getItemInternal(int index) {
+ return _ref.getInnerValueEval();
}
- }
+ }
+ private static final class AreaValueArray extends ValueArray {
+ private final AreaEval _ae;
+ private final int _width;
+
+ public AreaValueArray(AreaEval ae) {
+ super(ae.getWidth() * ae.getHeight());
+ _ae = ae;
+ _width = ae.getWidth();
+ }
+ protected ValueEval getItemInternal(int index) {
+ int rowIx = index / _width;
+ int colIx = index % _width;
+ return _ae.getRelativeValue(rowIx, colIx);
+ }
+ }
+
+ protected static interface Accumulator {
+ double accumulate(double x, double y);
+ }
+
+ /**
+ * Constructs a new instance of the Accumulator used to calculated this function
+ */
+ protected abstract Accumulator createAccumulator();
+
+ public final Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
+ if (args.length != 2) {
+ return ErrorEval.VALUE_INVALID;
+ }
- public final Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
- if(args.length != 2) {
- return ErrorEval.VALUE_INVALID;
- }
-
- double[][] values;
+ double result;
try {
- values = getValues(args[0], args[1]);
+ ValueVector vvX = createValueVector(args[0]);
+ ValueVector vvY = createValueVector(args[1]);
+ int size = vvX.getSize();
+ if (size == 0 || vvY.getSize() != size) {
+ return ErrorEval.NA;
+ }
+ result = evaluateInternal(vvX, vvY, size);
} catch (EvaluationException e) {
return e.getErrorEval();
}
- if (values==null
- || values[X] == null || values[Y] == null
- || values[X].length == 0 || values[Y].length == 0
- || values[X].length != values[Y].length) {
- return ErrorEval.VALUE_INVALID;
- }
-
- double d = evaluate(values[X], values[Y]);
- if (Double.isNaN(d) || Double.isInfinite(d)) {
+ if (Double.isNaN(result) || Double.isInfinite(result)) {
return ErrorEval.NUM_ERROR;
}
- return new NumberEval(d);
- }
- protected abstract double evaluate(double[] xArray, double[] yArray);
-
- /**
- * 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.
- */
- private static double[][] getNumberArray(Eval[] xops, Eval[] yops) throws EvaluationException {
-
- // check for errors first: size mismatch, value errors in x, value errors in y
-
- int nArrayItems = xops.length;
- if(nArrayItems != yops.length) {
- throw new EvaluationException(ErrorEval.NA);
- }
- for (int i = 0; i < xops.length; i++) {
- Eval eval = xops[i];
- if (eval instanceof ErrorEval) {
- throw new EvaluationException((ErrorEval) eval);
+ return new NumberEval(result);
+ }
+
+ private double evaluateInternal(ValueVector x, ValueVector y, int size)
+ throws EvaluationException {
+ Accumulator acc = createAccumulator();
+
+ // error handling is as if the x is fully evaluated before y
+ ErrorEval firstXerr = null;
+ ErrorEval firstYerr = null;
+ boolean accumlatedSome = false;
+ double result = 0.0;
+
+ for (int i = 0; i < size; i++) {
+ ValueEval vx = x.getItem(i);
+ ValueEval vy = y.getItem(i);
+ if (vx instanceof ErrorEval) {
+ if (firstXerr == null) {
+ firstXerr = (ErrorEval) vx;
+ continue;
+ }
}
- }
- for (int i = 0; i < yops.length; i++) {
- Eval eval = yops[i];
- if (eval instanceof ErrorEval) {
- throw new EvaluationException((ErrorEval) eval);
+ if (vy instanceof ErrorEval) {
+ if (firstYerr == null) {
+ firstYerr = (ErrorEval) vy;
+ continue;
+ }
+ }
+ // only count pairs if both elements are numbers
+ if (vx instanceof NumberEval && vy instanceof NumberEval) {
+ accumlatedSome = true;
+ NumberEval nx = (NumberEval) vx;
+ NumberEval ny = (NumberEval) vy;
+ result += acc.accumulate(nx.getNumberValue(), ny.getNumberValue());
+ } else {
+ // all other combinations of value types are silently ignored
}
}
-
- double[] xResult = new double[nArrayItems];
- double[] yResult = new double[nArrayItems];
-
- int count = 0;
-
- for (int i=0, iSize=nArrayItems; i<iSize; i++) {
- Eval xEval = xops[i];
- Eval yEval = yops[i];
-
- if (isNumberEval(xEval) && isNumberEval(yEval)) {
- xResult[count] = getDoubleValue(xEval);
- yResult[count] = getDoubleValue(yEval);
- if (Double.isNaN(xResult[count]) || Double.isNaN(xResult[count])) {
- throw new EvaluationException(ErrorEval.NUM_ERROR);
- }
- count++;
- }
- }
-
- return new double[][] {
- trimToSize(xResult, count),
- trimToSize(yResult, count),
- };
- }
-
- private static double[][] getValues(Eval argX, Eval argY) throws EvaluationException {
-
- if (argX instanceof ErrorEval) {
- throw new EvaluationException((ErrorEval) argX);
- }
- if (argY instanceof ErrorEval) {
- throw new EvaluationException((ErrorEval) argY);
- }
-
- Eval[] xEvals;
- Eval[] yEvals;
- if (argX instanceof AreaEval) {
- AreaEval ae = (AreaEval) argX;
- xEvals = ae.getValues();
- } else {
- xEvals = new Eval[] { argX, };
- }
-
- if (argY instanceof AreaEval) {
- AreaEval ae = (AreaEval) argY;
- yEvals = ae.getValues();
- } else {
- yEvals = new Eval[] { argY, };
- }
-
- return getNumberArray(xEvals, yEvals);
- }
-
- private static double[] trimToSize(double[] arr, int len) {
- double[] tarr = arr;
- if (arr.length > len) {
- tarr = new double[len];
- System.arraycopy(arr, 0, tarr, 0, len);
- }
- return tarr;
- }
-
- private static boolean isNumberEval(Eval eval) {
- boolean retval = false;
-
- if (eval instanceof NumberEval) {
- retval = true;
- }
- else if (eval instanceof RefEval) {
- RefEval re = (RefEval) eval;
- ValueEval ve = re.getInnerValueEval();
- retval = (ve instanceof NumberEval);
- }
-
- return retval;
- }
-
- private static double getDoubleValue(Eval eval) {
- double retval = 0;
- if (eval instanceof NumberEval) {
- NumberEval ne = (NumberEval) eval;
- retval = ne.getNumberValue();
- }
- else if (eval instanceof RefEval) {
- RefEval re = (RefEval) eval;
- ValueEval ve = re.getInnerValueEval();
- retval = (ve instanceof NumberEval)
- ? ((NumberEval) ve).getNumberValue()
- : Double.NaN;
- }
- else if (eval instanceof ErrorEval) {
- retval = Double.NaN;
- }
- return retval;
- }
+ if (firstXerr != null) {
+ throw new EvaluationException(firstXerr);
+ }
+ if (firstYerr != null) {
+ throw new EvaluationException(firstYerr);
+ }
+ if (!accumlatedSome) {
+ throw new EvaluationException(ErrorEval.DIV_ZERO);
+ }
+ return result;
+ }
+
+ private static ValueVector createValueVector(Eval arg) throws EvaluationException {
+ if (arg instanceof ErrorEval) {
+ throw new EvaluationException((ErrorEval) arg);
+ }
+ if (arg instanceof AreaEval) {
+ return new AreaValueArray((AreaEval) arg);
+ }
+ if (arg instanceof RefEval) {
+ return new RefValueArray((RefEval) arg);
+ }
+ if (arg instanceof ValueEval) {
+ return new SingleCellValueArray((ValueEval) arg);
+ }
+ throw new RuntimeException("Unexpected eval class (" + arg.getClass().getName() + ")");
+ }
}
};
AreaEval aeA = EvalFactory.createAreaEval("A1:A2", aValues);
AreaEval aeB = EvalFactory.createAreaEval("B1:B2", new ValueEval[2]);
- aeB.getValues()[1] = ErrorEval.REF_INVALID;
Eval[] args = { aeA, aeB, };
assertEquals(ErrorEval.REF_INVALID, invokeSumproduct(args));