removed AreaEval.getValues (initial work for bug 45358)

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@690761 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Josh Micich 2008-08-31 19:08:36 +00:00
parent bbe5c8d867
commit 4ca39e86fd
10 changed files with 315 additions and 307 deletions

View File

@ -61,13 +61,6 @@ public interface AreaEval extends ValueEval {
*/
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

View File

@ -77,11 +77,6 @@ abstract class AreaEvalBase implements AreaEval {
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;

View File

@ -69,5 +69,11 @@ public class NumberEval implements NumericValueEval, StringValueEval {
}
}
}
public final String toString() {
StringBuffer sb = new StringBuffer(64);
sb.append(getClass().getName()).append(" [");
sb.append(getStringValue());
sb.append("]");
return sb.toString();
}
}

View File

@ -1,28 +1,28 @@
/*
* 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/>
@ -51,15 +51,23 @@ public final class Index implements Function {
return ErrorEval.VALUE_INVALID;
}
Eval firstArg = args[0];
if(firstArg instanceof AreaEval) {
AreaEval reference = (AreaEval) firstArg;
if(!(firstArg instanceof AreaEval)) {
int rowIx = 0;
int columnIx = 0;
int areaIx = 0;
// 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() + ")");
}
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)
@ -68,41 +76,41 @@ public final class Index implements Function {
// 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;
}
}

View File

@ -126,30 +126,34 @@ public abstract class MultiOperandNumericFunction extends NumericFunction {
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();
}

View File

@ -1,22 +1,23 @@
/*
* 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/>
*
@ -30,7 +31,13 @@ package org.apache.poi.hssf.record.formula.functions;
*/
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;
}
}

View File

@ -1,22 +1,23 @@
/*
* 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/>
*
@ -30,7 +31,13 @@ package org.apache.poi.hssf.record.formula.functions;
*/
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;
}
}

View File

@ -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;
@ -30,7 +30,14 @@ 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;
}
}

View File

@ -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;
@ -24,180 +24,162 @@ 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.RefEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
import org.apache.poi.hssf.record.formula.functions.LookupUtils.ValueVector;
/**
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
*
*
*/
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;
public DoubleArrayPair(double[] xArray, double[] yArray) {
_xArray = xArray;
_yArray = yArray;
private static abstract class ValueArray implements ValueVector {
private final int _size;
protected ValueArray(int size) {
_size = size;
}
public double[] getXArray() {
return _xArray;
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);
}
public double[] getYArray() {
return _yArray;
protected abstract ValueEval getItemInternal(int index);
public final int getSize() {
return _size;
}
}
}
private static final class SingleCellValueArray extends ValueArray {
private final ValueEval _value;
public SingleCellValueArray(ValueEval value) {
super(1);
_value = value;
}
protected ValueEval getItemInternal(int index) {
return _value;
}
}
public final Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
if(args.length != 2) {
return ErrorEval.VALUE_INVALID;
}
double[][] values;
private static final class RefValueArray extends ValueArray {
private final RefEval _ref;
public RefValueArray(RefEval ref) {
super(1);
_ref = ref;
}
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;
}
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);
return new NumberEval(result);
}
/**
* 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);
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;
}
}
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
}
}
for (int i = 0; i < yops.length; i++) {
Eval eval = yops[i];
if (eval instanceof ErrorEval) {
throw new EvaluationException((ErrorEval) eval);
}
if (firstXerr != null) {
throw new EvaluationException(firstXerr);
}
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++;
}
if (firstYerr != null) {
throw new EvaluationException(firstYerr);
}
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 (!accumlatedSome) {
throw new EvaluationException(ErrorEval.DIV_ZERO);
}
if (argY instanceof ErrorEval) {
throw new EvaluationException((ErrorEval) argY);
return result;
}
private static ValueVector createValueVector(Eval arg) throws EvaluationException {
if (arg instanceof ErrorEval) {
throw new EvaluationException((ErrorEval) arg);
}
Eval[] xEvals;
Eval[] yEvals;
if (argX instanceof AreaEval) {
AreaEval ae = (AreaEval) argX;
xEvals = ae.getValues();
} else {
xEvals = new Eval[] { argX, };
if (arg instanceof AreaEval) {
return new AreaValueArray((AreaEval) arg);
}
if (argY instanceof AreaEval) {
AreaEval ae = (AreaEval) argY;
yEvals = ae.getValues();
} else {
yEvals = new Eval[] { argY, };
if (arg instanceof RefEval) {
return new RefValueArray((RefEval) arg);
}
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 (arg instanceof ValueEval) {
return new SingleCellValueArray((ValueEval) arg);
}
throw new RuntimeException("Unexpected eval class (" + arg.getClass().getName() + ")");
}
}

View File

@ -113,7 +113,6 @@ public final class TestSumproduct extends TestCase {
};
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));