Fixing error value handling for numeric functions. Refactored hierarchy.

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@693939 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Josh Micich 2008-09-10 19:23:43 +00:00
parent 27c3aeb55f
commit fdbcbf978b
20 changed files with 151 additions and 1205 deletions

View File

@ -1,19 +1,19 @@
/* /* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one or more Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0 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 not use this file except in compliance with
* the License. You may obtain a copy of the License at the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and See the License for the specific language governing permissions and
* limitations under the License. limitations under the License.
*/ ==================================================================== */
package org.apache.poi.hssf.record.formula.eval; package org.apache.poi.hssf.record.formula.eval;
@ -24,7 +24,7 @@ import org.apache.poi.hssf.record.formula.Ptg;
* @author Amol S. Deshmukh < amolweb at ya hoo dot com > * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
* *
*/ */
public final class ConcatEval extends StringOperationEval { public final class ConcatEval implements OperationEval {
private ConcatPtg delegate; private ConcatPtg delegate;
@ -37,19 +37,22 @@ public final class ConcatEval extends StringOperationEval {
return ErrorEval.VALUE_INVALID; return ErrorEval.VALUE_INVALID;
} }
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
try {
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
ValueEval ve = singleOperandEvaluate(args[i], srcRow, srcCol); ValueEval ve = OperandResolver.getSingleValue(args[i], srcRow, srcCol);
if (ve instanceof StringValueEval) { if (ve instanceof StringValueEval) {
StringValueEval sve = (StringValueEval) ve; StringValueEval sve = (StringValueEval) ve;
sb.append(sve.getStringValue()); sb.append(sve.getStringValue());
} } else if (ve instanceof BlankEval) {
else if (ve instanceof BlankEval) {
// do nothing // do nothing
} else { // must be an error eval
throw new RuntimeException("Unexpected value type ("
+ ve.getClass().getName() + ")");
} }
else { // must be an error eval
return ve;
} }
} catch (EvaluationException e) {
return e.getErrorEval();
} }
return new StringEval(sb.toString()); return new StringEval(sb.toString());

View File

@ -90,21 +90,21 @@ public abstract class FunctionEval implements OperationEval {
retval[10] = new Na(); // NA retval[10] = new Na(); // NA
retval[11] = new Npv(); // NPV retval[11] = new Npv(); // NPV
retval[12] = new Stdev(); // STDEV retval[12] = new Stdev(); // STDEV
retval[13] = NumericFunctionOneArg.DOLLAR; retval[13] = NumericFunction.DOLLAR;
retval[14] = new Fixed(); // FIXED retval[14] = new Fixed(); // FIXED
retval[15] = NumericFunctionOneArg.SIN; retval[15] = NumericFunction.SIN;
retval[16] = NumericFunctionOneArg.COS; retval[16] = NumericFunction.COS;
retval[17] = NumericFunctionOneArg.TAN; retval[17] = NumericFunction.TAN;
retval[18] = NumericFunctionOneArg.ATAN; retval[18] = NumericFunction.ATAN;
retval[19] = new Pi(); // PI retval[19] = new Pi(); // PI
retval[20] = NumericFunctionOneArg.SQRT; retval[20] = NumericFunction.SQRT;
retval[21] = NumericFunctionOneArg.EXP; retval[21] = NumericFunction.EXP;
retval[22] = NumericFunctionOneArg.LN; retval[22] = NumericFunction.LN;
retval[23] = NumericFunctionOneArg.LOG10; retval[23] = NumericFunction.LOG10;
retval[24] = NumericFunctionOneArg.ABS; retval[24] = NumericFunction.ABS;
retval[25] = NumericFunctionOneArg.INT; retval[25] = NumericFunction.INT;
retval[26] = NumericFunctionOneArg.SIGN; retval[26] = NumericFunction.SIGN;
retval[27] = new Round(); // ROUND retval[27] = NumericFunction.ROUND;
retval[28] = new Lookup(); // LOOKUP retval[28] = new Lookup(); // LOOKUP
retval[29] = new Index(); // INDEX retval[29] = new Index(); // INDEX
retval[30] = new Rept(); // REPT retval[30] = new Rept(); // REPT
@ -116,7 +116,7 @@ public abstract class FunctionEval implements OperationEval {
retval[36] = new And(); // AND retval[36] = new And(); // AND
retval[37] = new Or(); // OR retval[37] = new Or(); // OR
retval[38] = new Not(); // NOT retval[38] = new Not(); // NOT
retval[39] = new Mod(); // MOD retval[39] = NumericFunction.MOD;
retval[40] = new Dcount(); // DCOUNT retval[40] = new Dcount(); // DCOUNT
retval[41] = new Dsum(); // DSUM retval[41] = new Dsum(); // DSUM
retval[42] = new Daverage(); // DAVERAGE retval[42] = new Daverage(); // DAVERAGE
@ -141,7 +141,7 @@ public abstract class FunctionEval implements OperationEval {
retval[62] = new Irr(); // IRR retval[62] = new Irr(); // IRR
retval[63] = new Rand(); // RAND retval[63] = new Rand(); // RAND
retval[64] = new Match(); // MATCH retval[64] = new Match(); // MATCH
retval[65] = new Date(); // DATE retval[65] = DateFunc.instance; // DATE
retval[66] = new Time(); // TIME retval[66] = new Time(); // TIME
retval[67] = CalendarFieldFunction.DAY; // DAY retval[67] = CalendarFieldFunction.DAY; // DAY
retval[68] = CalendarFieldFunction.MONTH; // MONTH retval[68] = CalendarFieldFunction.MONTH; // MONTH
@ -173,9 +173,9 @@ public abstract class FunctionEval implements OperationEval {
retval[94] = new Activecell(); // ACTIVECELL retval[94] = new Activecell(); // ACTIVECELL
retval[95] = new NotImplementedFunction(); // SELECTION retval[95] = new NotImplementedFunction(); // SELECTION
retval[96] = new Result(); // RESULT retval[96] = new Result(); // RESULT
retval[97] = new Atan2(); // ATAN2 retval[97] = NumericFunction.ATAN2;
retval[98] = NumericFunctionOneArg.ASIN; retval[98] = NumericFunction.ASIN;
retval[99] = NumericFunctionOneArg.ACOS; retval[99] = NumericFunction.ACOS;
retval[100] = new Choose(); // CHOOSE retval[100] = new Choose(); // CHOOSE
retval[101] = new Hlookup(); // HLOOKUP retval[101] = new Hlookup(); // HLOOKUP
retval[102] = new Vlookup(); // VLOOKUP retval[102] = new Vlookup(); // VLOOKUP
@ -185,7 +185,7 @@ public abstract class FunctionEval implements OperationEval {
retval[106] = new NotImplementedFunction(); // GETFORMULA retval[106] = new NotImplementedFunction(); // GETFORMULA
retval[107] = new NotImplementedFunction(); // GETNAME retval[107] = new NotImplementedFunction(); // GETNAME
retval[108] = new Setvalue(); // SETVALUE retval[108] = new Setvalue(); // SETVALUE
retval[109] = new Log(); // LOG retval[109] = NumericFunction.LOG;
retval[110] = new Exec(); // EXEC retval[110] = new Exec(); // EXEC
retval[111] = new Char(); // CHAR retval[111] = new Char(); // CHAR
retval[112] = new Lower(); // LOWER retval[112] = new Lower(); // LOWER
@ -256,7 +256,7 @@ public abstract class FunctionEval implements OperationEval {
retval[181] = new Help(); // HELP retval[181] = new Help(); // HELP
retval[182] = new NotImplementedFunction(); // GETBAR retval[182] = new NotImplementedFunction(); // GETBAR
retval[183] = new Product(); // PRODUCT retval[183] = new Product(); // PRODUCT
retval[184] = NumericFunctionOneArg.FACT; retval[184] = NumericFunction.FACT;
retval[185] = new NotImplementedFunction(); // GETCELL retval[185] = new NotImplementedFunction(); // GETCELL
retval[186] = new NotImplementedFunction(); // GETWORKSPACE retval[186] = new NotImplementedFunction(); // GETWORKSPACE
retval[187] = new NotImplementedFunction(); // GETWINDOW retval[187] = new NotImplementedFunction(); // GETWINDOW
@ -282,8 +282,8 @@ public abstract class FunctionEval implements OperationEval {
retval[209] = new Rightb(); // RIGHTB retval[209] = new Rightb(); // RIGHTB
retval[210] = new Midb(); // MIDB retval[210] = new Midb(); // MIDB
retval[211] = new Lenb(); // LENB retval[211] = new Lenb(); // LENB
retval[212] = new Roundup(); // ROUNDUP retval[212] = NumericFunction.ROUNDUP;
retval[213] = new Rounddown(); // ROUNDDOWN retval[213] = NumericFunction.ROUNDDOWN;
retval[214] = new Asc(); // ASC retval[214] = new Asc(); // ASC
retval[215] = new Dbcs(); // DBCS retval[215] = new Dbcs(); // DBCS
retval[216] = new Rank(); // RANK retval[216] = new Rank(); // RANK
@ -293,12 +293,12 @@ public abstract class FunctionEval implements OperationEval {
retval[222] = new Vdb(); // VDB retval[222] = new Vdb(); // VDB
retval[227] = new Median(); // MEDIAN retval[227] = new Median(); // MEDIAN
retval[228] = new Sumproduct(); // SUMPRODUCT retval[228] = new Sumproduct(); // SUMPRODUCT
retval[229] = NumericFunctionOneArg.SINH; retval[229] = NumericFunction.SINH;
retval[230] = NumericFunctionOneArg.COSH; retval[230] = NumericFunction.COSH;
retval[231] = NumericFunctionOneArg.TANH; retval[231] = NumericFunction.TANH;
retval[232] = NumericFunctionOneArg.ASINH; retval[232] = NumericFunction.ASINH;
retval[233] = NumericFunctionOneArg.ACOSH; retval[233] = NumericFunction.ACOSH;
retval[234] = NumericFunctionOneArg.ATANH; retval[234] = NumericFunction.ATANH;
retval[235] = new Dget(); // DGET retval[235] = new Dget(); // DGET
retval[236] = new NotImplementedFunction(); // CREATEOBJECT retval[236] = new NotImplementedFunction(); // CREATEOBJECT
retval[237] = new Volatile(); // VOLATILE retval[237] = new Volatile(); // VOLATILE
@ -338,7 +338,7 @@ public abstract class FunctionEval implements OperationEval {
retval[273] = new Binomdist(); // BINOMDIST retval[273] = new Binomdist(); // BINOMDIST
retval[274] = new Chidist(); // CHIDIST retval[274] = new Chidist(); // CHIDIST
retval[275] = new Chiinv(); // CHIINV retval[275] = new Chiinv(); // CHIINV
retval[276] = new Combin(); // COMBIN retval[276] = NumericFunction.COMBIN;
retval[277] = new Confidence(); // CONFIDENCE retval[277] = new Confidence(); // CONFIDENCE
retval[278] = new Critbinom(); // CRITBINOM retval[278] = new Critbinom(); // CRITBINOM
retval[279] = new Even(); // EVEN retval[279] = new Even(); // EVEN
@ -347,10 +347,10 @@ public abstract class FunctionEval implements OperationEval {
retval[282] = new Finv(); // FINV retval[282] = new Finv(); // FINV
retval[283] = new Fisher(); // FISHER retval[283] = new Fisher(); // FISHER
retval[284] = new Fisherinv(); // FISHERINV retval[284] = new Fisherinv(); // FISHERINV
retval[285] = new Floor(); // FLOOR retval[285] = NumericFunction.FLOOR;
retval[286] = new Gammadist(); // GAMMADIST retval[286] = new Gammadist(); // GAMMADIST
retval[287] = new Gammainv(); // GAMMAINV retval[287] = new Gammainv(); // GAMMAINV
retval[288] = new Ceiling(); // CEILING retval[288] = NumericFunction.CEILING;
retval[289] = new Hypgeomdist(); // HYPGEOMDIST retval[289] = new Hypgeomdist(); // HYPGEOMDIST
retval[290] = new Lognormdist(); // LOGNORMDIST retval[290] = new Lognormdist(); // LOGNORMDIST
retval[291] = new Loginv(); // LOGINV retval[291] = new Loginv(); // LOGINV
@ -398,13 +398,13 @@ public abstract class FunctionEval implements OperationEval {
retval[334] = new NotImplementedFunction(); // MOVIECOMMAND retval[334] = new NotImplementedFunction(); // MOVIECOMMAND
retval[335] = new NotImplementedFunction(); // GETMOVIE retval[335] = new NotImplementedFunction(); // GETMOVIE
retval[336] = new Concatenate(); // CONCATENATE retval[336] = new Concatenate(); // CONCATENATE
retval[337] = new Power(); // POWER retval[337] = NumericFunction.POWER;
retval[338] = new NotImplementedFunction(); // PIVOTADDDATA retval[338] = new NotImplementedFunction(); // PIVOTADDDATA
retval[339] = new NotImplementedFunction(); // GETPIVOTTABLE retval[339] = new NotImplementedFunction(); // GETPIVOTTABLE
retval[340] = new NotImplementedFunction(); // GETPIVOTFIELD retval[340] = new NotImplementedFunction(); // GETPIVOTFIELD
retval[341] = new NotImplementedFunction(); // GETPIVOTITEM retval[341] = new NotImplementedFunction(); // GETPIVOTITEM
retval[342] = NumericFunctionOneArg.RADIANS; retval[342] = NumericFunction.RADIANS;
retval[343] = NumericFunctionOneArg.DEGREES; retval[343] = NumericFunction.DEGREES;
retval[344] = new Subtotal(); // SUBTOTAL retval[344] = new Subtotal(); // SUBTOTAL
retval[345] = new Sumif(); // SUMIF retval[345] = new Sumif(); // SUMIF
retval[346] = new Countif(); // COUNTIF retval[346] = new Countif(); // COUNTIF

View File

@ -1,84 +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 6, 2005
*
*/
package org.apache.poi.hssf.record.formula.functions;
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.NumberEval;
import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
/**
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
*
*/
public class Atan2 extends NumericFunction {
public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
double d0 = 0;
double d1 = 0;
ValueEval retval = null;
switch (operands.length) {
default:
retval = ErrorEval.VALUE_INVALID;
break;
case 2:
ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
if (ve instanceof NumericValueEval) {
NumericValueEval ne = (NumericValueEval) ve;
d0 = ne.getNumberValue();
}
else if (ve instanceof BlankEval) {
// do nothing
}
else {
retval = ErrorEval.NUM_ERROR;
}
if (retval == null) {
ve = singleOperandEvaluate(operands[1], srcRow, srcCol);
if (ve instanceof NumericValueEval) {
NumericValueEval ne = (NumericValueEval) ve;
d1 = ne.getNumberValue();
}
else if (ve instanceof BlankEval) {
// do nothing
}
else {
retval = ErrorEval.NUM_ERROR;
}
}
}
if (retval == null) {
double d = (d0 == d1 && d1 == 0)
? Double.NaN
: Math.atan2(d1, d0);
retval = (Double.isNaN(d) || Double.isInfinite(d))
? (ValueEval) ErrorEval.NUM_ERROR
: new NumberEval(d);
}
return retval;
}
}

View File

@ -1,82 +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.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.NumberEval;
import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
/**
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
*
*/
public class Ceiling extends NumericFunction {
public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
double d0 = 0;
double d1 = 0;
ValueEval retval = null;
switch (operands.length) {
default:
retval = ErrorEval.VALUE_INVALID;
break;
case 2:
ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
if (ve instanceof NumericValueEval) {
NumericValueEval ne = (NumericValueEval) ve;
d0 = ne.getNumberValue();
}
else if (ve instanceof BlankEval) {
// do nothing
}
else {
retval = ErrorEval.NUM_ERROR;
}
if (retval == null) {
ve = singleOperandEvaluate(operands[1], srcRow, srcCol);
if (ve instanceof NumericValueEval) {
NumericValueEval ne = (NumericValueEval) ve;
d1 = ne.getNumberValue();
}
else if (ve instanceof BlankEval) {
// do nothing
}
else {
retval = ErrorEval.NUM_ERROR;
}
}
}
if (retval == null) {
double d = MathX.ceiling(d0, d1);
retval = (Double.isNaN(d) || Double.isInfinite(d))
? (ValueEval) ErrorEval.NUM_ERROR
: new NumberEval(d);
}
return retval;
}
}

View File

@ -1,87 +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.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.NumberEval;
import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
/**
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
*
*/
public class Combin extends NumericFunction {
public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
double d0 = 0;
double d1 = 0;
ValueEval retval = null;
switch (operands.length) {
default:
retval = ErrorEval.VALUE_INVALID;
break;
case 2:
ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
if (ve instanceof NumericValueEval) {
NumericValueEval ne = (NumericValueEval) ve;
d0 = ne.getNumberValue();
}
else if (ve instanceof BlankEval) {
// do nothing
}
else {
retval = ErrorEval.NUM_ERROR;
}
if (retval == null) {
ve = singleOperandEvaluate(operands[1], srcRow, srcCol);
if (ve instanceof NumericValueEval) {
NumericValueEval ne = (NumericValueEval) ve;
d1 = ne.getNumberValue();
}
else if (ve instanceof BlankEval) {
// do nothing
}
else {
retval = ErrorEval.NUM_ERROR;
}
}
}
if (retval == null) {
if (d0 > Integer.MAX_VALUE || d1 > Integer.MAX_VALUE) {
retval = ErrorEval.NUM_ERROR;
}
else {
double d = MathX.nChooseK((int) d0, (int) d1);
retval = (Double.isNaN(d) || Double.isInfinite(d))
? (ValueEval) ErrorEval.NUM_ERROR
: new NumberEval(d);
}
}
return retval;
}
}

View File

@ -1,114 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.poi.hssf.record.formula.functions;
import java.util.Calendar;
import java.util.GregorianCalendar;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.record.formula.eval.Eval;
import org.apache.poi.hssf.record.formula.eval.RefEval;
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.ValueEval;
import org.apache.poi.hssf.record.formula.eval.NumberEval;
import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
/**
* @author Pavel Krupets (pkrupets at palmtreebusiness dot com)
*/
public class Date extends NumericFunction {
/**
* @see org.apache.poi.hssf.record.formula.functions.Function#evaluate(org.apache.poi.hssf.record.formula.eval.Eval[], int, short)
*/
public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
if (operands.length == 3) {
ValueEval ve[] = new ValueEval[3];
ve[0] = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol);
ve[1] = singleOperandEvaluate(operands[1], srcCellRow, srcCellCol);
ve[2] = singleOperandEvaluate(operands[2], srcCellRow, srcCellCol);
if (validValues(ve)) {
int year = getYear(ve[0]);
int month = (int) ((NumericValueEval) ve[1]).getNumberValue() - 1;
int day = (int) ((NumericValueEval) ve[2]).getNumberValue();
if (year < 0 || month < 0 || day < 0) {
return ErrorEval.VALUE_INVALID;
}
if (year == 1900 && month == Calendar.FEBRUARY && day == 29) {
return new NumberEval(60.0);
}
if (year == 1900) {
if ((month == Calendar.JANUARY && day >= 60) ||
(month == Calendar.FEBRUARY && day >= 30))
{
day--;
}
}
Calendar c = new GregorianCalendar();
c.set(year, month, day, 0, 0, 0);
c.set(Calendar.MILLISECOND, 0);
return new NumberEval(HSSFDateUtil.getExcelDate(c.getTime(), false)); // XXX fix 1900/1904 problem
}
}
return ErrorEval.VALUE_INVALID;
}
private int getYear(ValueEval ve) {
int year = (int) ((NumericValueEval) ve).getNumberValue();
if (year < 0) {
return -1;
}
return year < 1900 ? 1900 + year : year;
}
private boolean validValues(ValueEval[] values) {
for (int i = 0; i < values.length; i++) {
ValueEval value = values[i];
if (value instanceof RefEval) {
RefEval re = (RefEval) value;
ValueEval ive = re.getInnerValueEval();
if (ive instanceof BlankEval) {
value = new NumberEval(0);
} else if (ive instanceof NumericValueEval) {
value = ive;
} else {
return false;
}
}
if (!(value instanceof NumericValueEval)) {
return false;
}
}
return true;
}
}

View File

@ -0,0 +1,76 @@
/* ====================================================================
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 java.util.Calendar;
import java.util.GregorianCalendar;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.EvaluationException;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
/**
* @author Pavel Krupets (pkrupets at palmtreebusiness dot com)
*/
public final class DateFunc extends NumericFunction.MultiArg {
public static final Function instance = new DateFunc();
private DateFunc() {
super(3,3);
}
protected double evaluate(double[] ds) throws EvaluationException {
int year = getYear(ds[0]);
int month = (int) ds[1] - 1;
int day = (int) ds[2];
if (year < 0 || month < 0 || day < 0) {
throw new EvaluationException(ErrorEval.VALUE_INVALID);
}
if (year == 1900 && month == Calendar.FEBRUARY && day == 29) {
return 60.0;
}
if (year == 1900) {
if ((month == Calendar.JANUARY && day >= 60) ||
(month == Calendar.FEBRUARY && day >= 30))
{
day--;
}
}
Calendar c = new GregorianCalendar();
c.set(year, month, day, 0, 0, 0);
c.set(Calendar.MILLISECOND, 0);
return HSSFDateUtil.getExcelDate(c.getTime(), false); // XXX fix 1900/1904 problem
}
private static int getYear(double d) {
int year = (int)d;
if (year < 0) {
return -1;
}
return year < 1900 ? 1900 + year : year;
}
}

View File

@ -22,7 +22,7 @@ package org.apache.poi.hssf.record.formula.functions;
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt; * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
* *
*/ */
public final class Even extends NumericFunctionOneArg { public final class Even extends NumericFunction.OneArg {
private static final long PARITY_MASK = 0xFFFFFFFFFFFFFFFEL; private static final long PARITY_MASK = 0xFFFFFFFFFFFFFFFEL;

View File

@ -1,82 +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.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.NumberEval;
import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
/**
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
*
*/
public class Floor extends NumericFunction {
public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
double d0 = 0;
double d1 = 0;
ValueEval retval = null;
switch (operands.length) {
default:
retval = ErrorEval.VALUE_INVALID;
break;
case 2:
ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
if (ve instanceof NumericValueEval) {
NumericValueEval ne = (NumericValueEval) ve;
d0 = ne.getNumberValue();
}
else if (ve instanceof BlankEval) {
// do nothing
}
else {
retval = ErrorEval.NUM_ERROR;
}
if (retval == null) {
ve = singleOperandEvaluate(operands[1], srcRow, srcCol);
if (ve instanceof NumericValueEval) {
NumericValueEval ne = (NumericValueEval) ve;
d1 = ne.getNumberValue();
}
else if (ve instanceof BlankEval) {
// do nothing
}
else {
retval = ErrorEval.NUM_ERROR;
}
}
}
if (retval == null) {
double d = MathX.floor(d0, d1);
retval = (Double.isNaN(d) || Double.isInfinite(d))
? (ValueEval) ErrorEval.NUM_ERROR
: new NumberEval(d);
}
return retval;
}
}

View File

@ -1,87 +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 6, 2005
*
*/
package org.apache.poi.hssf.record.formula.functions;
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.NumberEval;
import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
/**
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
* Log: LOG(number,[base])
*/
public class Log extends NumericFunction {
private static final double DEFAULT_BASE = 10;
public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
double d = 0;
double base = DEFAULT_BASE;
double num = 0;
ValueEval retval = null;
switch (operands.length) {
default:
retval = ErrorEval.VALUE_INVALID;
break;
case 2: // second arg is base
ValueEval ve = singleOperandEvaluate(operands[1], srcRow, srcCol);
if (ve instanceof NumericValueEval) {
NumericValueEval ne = (NumericValueEval) ve;
base = ne.getNumberValue();
}
else if (ve instanceof BlankEval) {
// do nothing
}
else {
retval = ErrorEval.NUM_ERROR;
}
case 1: // first arg is number
if (retval == null) {
ValueEval vev = singleOperandEvaluate(operands[0], srcRow, srcCol);
if (vev instanceof NumericValueEval) {
NumericValueEval ne = (NumericValueEval) vev;
num = ne.getNumberValue();
}
else if (vev instanceof BlankEval) {
// do nothing
}
else {
retval = ErrorEval.NUM_ERROR;
}
}
}
if (retval == null) {
d = (base == E)
? Math.log(num)
: Math.log(num) / Math.log(base);
retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
}
return retval;
}
}

View File

@ -1,87 +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.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.NumberEval;
import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
/**
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
*
*/
public class Mod extends NumericFunction {
public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
double d0 = 0;
double d1 = 0;
ValueEval retval = null;
switch (operands.length) {
default:
retval = ErrorEval.VALUE_INVALID;
break;
case 2:
ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
if (ve instanceof NumericValueEval) {
NumericValueEval ne = (NumericValueEval) ve;
d0 = ne.getNumberValue();
}
else if (ve instanceof BlankEval) {
// do nothing
}
else {
retval = ErrorEval.NUM_ERROR;
}
if (retval == null) {
ve = singleOperandEvaluate(operands[1], srcRow, srcCol);
if (ve instanceof NumericValueEval) {
NumericValueEval ne = (NumericValueEval) ve;
d1 = ne.getNumberValue();
}
else if (ve instanceof BlankEval) {
// do nothing
}
else {
retval = ErrorEval.NUM_ERROR;
}
}
}
if (retval == null) {
if (d1 == 0) {
retval = ErrorEval.DIV_ZERO;
}
else {
double d = MathX.mod(d0, d1);
retval = (Double.isNaN(d) || Double.isInfinite(d))
? (ValueEval) ErrorEval.NUM_ERROR
: new NumberEval(d);
}
}
return retval;
}
}

View File

@ -1,172 +0,0 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.hssf.record.formula.functions;
import org.apache.poi.hssf.record.formula.eval.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.OperandResolver;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
/**
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
*
*/
public abstract class NumericFunctionOneArg implements Function {
public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
if (args.length != 1) {
return ErrorEval.VALUE_INVALID;
}
try {
ValueEval ve = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol);
double d = OperandResolver.coerceValueToDouble(ve);
if (Double.isNaN(d) || Double.isInfinite(d)) {
return ErrorEval.NUM_ERROR;
}
double result = evaluate(d);
if (Double.isNaN(result) || Double.isInfinite(result)) {
return ErrorEval.NUM_ERROR;
}
return new NumberEval(result);
} catch (EvaluationException e) {
return e.getErrorEval();
}
}
protected abstract double evaluate(double d);
public static final Function ABS = new NumericFunctionOneArg() {
protected double evaluate(double d) {
return Math.abs(d);
}
};
public static final Function ACOS = new NumericFunctionOneArg() {
protected double evaluate(double d) {
return Math.acos(d);
}
};
public static final Function ACOSH = new NumericFunctionOneArg() {
protected double evaluate(double d) {
return MathX.acosh(d);
}
};
public static final Function ASIN = new NumericFunctionOneArg() {
protected double evaluate(double d) {
return Math.asin(d);
}
};
public static final Function ASINH = new NumericFunctionOneArg() {
protected double evaluate(double d) {
return MathX.asinh(d);
}
};
public static final Function ATAN = new NumericFunctionOneArg() {
protected double evaluate(double d) {
return Math.atan(d);
}
};
public static final Function ATANH = new NumericFunctionOneArg() {
protected double evaluate(double d) {
return MathX.atanh(d);
}
};
public static final Function COS = new NumericFunctionOneArg() {
protected double evaluate(double d) {
return Math.cos(d);
}
};
public static final Function COSH = new NumericFunctionOneArg() {
protected double evaluate(double d) {
return MathX.cosh(d);
}
};
public static final Function DEGREES = new NumericFunctionOneArg() {
protected double evaluate(double d) {
return Math.toDegrees(d);
}
};
public static final Function DOLLAR = new NumericFunctionOneArg() {
protected double evaluate(double d) {
return d;
}
};
public static final Function EXP = new NumericFunctionOneArg() {
protected double evaluate(double d) {
return Math.pow(Math.E, d);
}
};
public static final Function FACT = new NumericFunctionOneArg() {
protected double evaluate(double d) {
return MathX.factorial((int)d);
}
};
public static final Function INT = new NumericFunctionOneArg() {
protected double evaluate(double d) {
return Math.round(d-0.5);
}
};
public static final Function LN = new NumericFunctionOneArg() {
protected double evaluate(double d) {
return Math.log(d);
}
};
static final double LOG_10_TO_BASE_e = Math.log(10);
public static final Function LOG10 = new NumericFunctionOneArg() {
protected double evaluate(double d) {
return Math.log(d) / LOG_10_TO_BASE_e;
}
};
public static final Function RADIANS = new NumericFunctionOneArg() {
protected double evaluate(double d) {
return Math.toRadians(d);
}
};
public static final Function SIGN = new NumericFunctionOneArg() {
protected double evaluate(double d) {
return MathX.sign(d);
}
};
public static final Function SIN = new NumericFunctionOneArg() {
protected double evaluate(double d) {
return Math.sin(d);
}
};
public static final Function SINH = new NumericFunctionOneArg() {
protected double evaluate(double d) {
return MathX.sinh(d);
}
};
public static final Function SQRT = new NumericFunctionOneArg() {
protected double evaluate(double d) {
return Math.sqrt(d);
}
};
public static final Function TAN = new NumericFunctionOneArg() {
protected double evaluate(double d) {
return Math.tan(d);
}
};
public static final Function TANH = new NumericFunctionOneArg() {
protected double evaluate(double d) {
return MathX.tanh(d);
}
};
}

View File

@ -22,7 +22,7 @@ package org.apache.poi.hssf.record.formula.functions;
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt; * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
* *
*/ */
public final class Odd extends NumericFunctionOneArg { public final class Odd extends NumericFunction.OneArg {
private static final long PARITY_MASK = 0xFFFFFFFFFFFFFFFEL; private static final long PARITY_MASK = 0xFFFFFFFFFFFFFFFEL;
protected double evaluate(double d) { protected double evaluate(double d) {

View File

@ -1,80 +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 6, 2005
*
*/
package org.apache.poi.hssf.record.formula.functions;
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.NumberEval;
import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
/**
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
*
*/
public class Power extends NumericFunction {
public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
double d0 = 0;
double d1 = 0;
ValueEval retval = null;
switch (operands.length) {
default:
retval = ErrorEval.VALUE_INVALID;
break;
case 2:
ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
if (ve instanceof NumericValueEval) {
NumericValueEval ne = (NumericValueEval) ve;
d0 = ne.getNumberValue();
}
else if (ve instanceof BlankEval) {
// do nothing
}
else {
retval = ErrorEval.NUM_ERROR;
}
if (retval == null) {
ValueEval vev = singleOperandEvaluate(operands[1], srcRow, srcCol);
if (vev instanceof NumericValueEval) {
NumericValueEval ne = (NumericValueEval) vev;
d1 = ne.getNumberValue();
}
else if (vev instanceof BlankEval) {
// do nothing
}
else {
retval = ErrorEval.NUM_ERROR;
}
}
}
if (retval == null) {
double d = Math.pow(d0, d1);
retval = (Double.isNaN(d) || Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
}
return retval;
}
}

View File

@ -1,83 +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.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.NumberEval;
import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
public class Round extends NumericFunction {
public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
double d0 = 0;
double d1 = 0;
ValueEval retval = null;
switch (operands.length) {
default:
retval = ErrorEval.VALUE_INVALID;
break;
case 2:
ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
if (ve instanceof NumericValueEval) {
NumericValueEval ne = (NumericValueEval) ve;
d0 = ne.getNumberValue();
}
else if (ve instanceof BlankEval) {
// do nothing
}
else {
retval = ErrorEval.NUM_ERROR;
}
if (retval == null) {
ve = singleOperandEvaluate(operands[1], srcRow, srcCol);
if (ve instanceof NumericValueEval) {
NumericValueEval ne = (NumericValueEval) ve;
d1 = ne.getNumberValue();
}
else if (ve instanceof BlankEval) {
// do nothing
}
else {
retval = ErrorEval.NUM_ERROR;
}
}
}
if (retval == null) {
double d;
if (d0 > Integer.MAX_VALUE) {
d = (Double.isNaN(d0) || Double.isInfinite(d0))
? Double.NaN
: 0;
}
else {
d = MathX.round(d0, (int) d1);
}
retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
}
return retval;
}
}

View File

@ -1,86 +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.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.NumberEval;
import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
public class Rounddown extends NumericFunction {
public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
double d0 = 0;
double d1 = 0;
ValueEval retval = null;
switch (operands.length) {
default:
retval = ErrorEval.VALUE_INVALID;
break;
case 2:
ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
if(ve instanceof ErrorEval) {
return ve;
}
if (ve instanceof NumericValueEval) {
NumericValueEval ne = (NumericValueEval) ve;
d0 = ne.getNumberValue();
}
else if (ve instanceof BlankEval) {
// do nothing
}
else {
retval = ErrorEval.NUM_ERROR;
}
if (retval == null) {
ve = singleOperandEvaluate(operands[1], srcRow, srcCol);
if (ve instanceof NumericValueEval) {
NumericValueEval ne = (NumericValueEval) ve;
d1 = ne.getNumberValue();
}
else if (ve instanceof BlankEval) {
// do nothing
}
else {
retval = ErrorEval.NUM_ERROR;
}
}
}
if (retval == null) {
double d;
if (d0 > Integer.MAX_VALUE) {
d = (Double.isInfinite(d0))
? Double.NaN
: 0;
}
else {
d = MathX.roundDown(d0, (int) d1);
}
retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
}
return retval;
}
}

View File

@ -1,88 +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.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.NumberEval;
import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
public class Roundup extends NumericFunction {
public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
double d0 = 0;
double d1 = 0;
ValueEval retval = null;
switch (operands.length) {
default:
retval = ErrorEval.VALUE_INVALID;
break;
case 2:
ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
if(ve instanceof ErrorEval) {
return ve;
}
if (ve instanceof NumericValueEval) {
NumericValueEval ne = (NumericValueEval) ve;
d0 = ne.getNumberValue();
}
else if (ve instanceof BlankEval) {
// do nothing
}
else {
retval = ErrorEval.NUM_ERROR;
}
if (retval == null) {
ve = singleOperandEvaluate(operands[1], srcRow, srcCol);
if (ve instanceof NumericValueEval) {
NumericValueEval ne = (NumericValueEval) ve;
d1 = ne.getNumberValue();
}
else if (ve instanceof BlankEval) {
// do nothing
}
else {
retval = ErrorEval.NUM_ERROR;
}
}
}
if (retval == null) {
double d;
if (d0 > Integer.MAX_VALUE) {
d = (Double.isNaN(d0))
? Double.NaN
: 0;
}
else {
d = MathX.roundUp(d0, (int) d1);
}
retval = (Double.isNaN(d) || Double.isInfinite(d))
? (ValueEval) ErrorEval.NUM_ERROR
: new NumberEval(d);
}
return retval;
}
}

View File

@ -21,13 +21,11 @@ import junit.framework.AssertionFailedError;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.hssf.record.formula.RefPtg;
import org.apache.poi.hssf.record.formula.eval.AreaEval; 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.BlankEval;
import org.apache.poi.hssf.record.formula.eval.BoolEval; import org.apache.poi.hssf.record.formula.eval.BoolEval;
import org.apache.poi.hssf.record.formula.eval.Eval; 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.NumberEval;
import org.apache.poi.hssf.record.formula.eval.Ref2DEval;
import org.apache.poi.hssf.record.formula.eval.StringEval; import org.apache.poi.hssf.record.formula.eval.StringEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval; import org.apache.poi.hssf.record.formula.eval.ValueEval;
import org.apache.poi.hssf.record.formula.functions.CountUtils.I_MatchPredicate; import org.apache.poi.hssf.record.formula.functions.CountUtils.I_MatchPredicate;

View File

@ -17,24 +17,25 @@
package org.apache.poi.hssf.record.formula.functions; package org.apache.poi.hssf.record.formula.functions;
import junit.framework.TestCase;
import org.apache.poi.hssf.record.formula.eval.ErrorEval; 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.Eval;
import org.apache.poi.hssf.record.formula.eval.NumberEval; import org.apache.poi.hssf.record.formula.eval.NumberEval;
import org.apache.poi.hssf.record.formula.eval.StringEval; import org.apache.poi.hssf.record.formula.eval.StringEval;
import junit.framework.TestCase;
/** /**
* Test cases for ROUND(), ROUNDUP(), ROUNDDOWN() * Test cases for ROUND(), ROUNDUP(), ROUNDDOWN()
* *
* @author Josh Micich * @author Josh Micich
*/ */
public final class TestRoundFuncs extends TestCase { public final class TestRoundFuncs extends TestCase {
private static final NumericFunction F = null;
public void testRounddownWithStringArg() { public void testRounddownWithStringArg() {
Eval strArg = new StringEval("abc"); Eval strArg = new StringEval("abc");
Eval[] args = { strArg, new NumberEval(2), }; Eval[] args = { strArg, new NumberEval(2), };
Eval result = new Rounddown().evaluate(args, -1, (short)-1); Eval result = F.ROUNDDOWN.evaluate(args, -1, (short)-1);
assertEquals(ErrorEval.VALUE_INVALID, result); assertEquals(ErrorEval.VALUE_INVALID, result);
} }
@ -42,7 +43,7 @@ public final class TestRoundFuncs extends TestCase {
Eval strArg = new StringEval("abc"); Eval strArg = new StringEval("abc");
Eval[] args = { strArg, new NumberEval(2), }; Eval[] args = { strArg, new NumberEval(2), };
Eval result = new Roundup().evaluate(args, -1, (short)-1); Eval result = F.ROUNDUP.evaluate(args, -1, (short)-1);
assertEquals(ErrorEval.VALUE_INVALID, result); assertEquals(ErrorEval.VALUE_INVALID, result);
} }