]> source.dussan.org Git - poi.git/commitdiff
New formula eval stuff - added functions and refactored, by Amol
authorAvik Sengupta <avik@apache.org>
Thu, 9 Jun 2005 18:34:57 +0000 (18:34 +0000)
committerAvik Sengupta <avik@apache.org>
Thu, 9 Jun 2005 18:34:57 +0000 (18:34 +0000)
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@353714 13f79535-47bb-0310-9956-ffa450edef68

83 files changed:
src/java/org/apache/poi/hssf/record/formula/AbstractFunctionPtg.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/AddEval.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/DivideEval.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ErrorEval.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/MultiplyEval.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/NumberEval.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/PowerEval.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/RelationalOperationEval.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/StringEval.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/SubtractEval.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/UnaryMinusEval.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/UnaryPlusEval.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ValueEvalToNumericXlator.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Abs.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Acos.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Acosh.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Asin.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Asinh.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Atan.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Atan2.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Atanh.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Avedev.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Average.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Averagea.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ceiling.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Column.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Combin.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Concatenate.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Cos.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Cosh.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Degrees.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Devsq.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dollar.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Even.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Exact.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Exp.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Fact.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Floor.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Int.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/IsError.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Isblank.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Large.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Len.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ln.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Log.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Log10.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Lower.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Max.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Maxa.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Median.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Min.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mina.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mod.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mode.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/NumericFunction.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Odd.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Power.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Product.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Radians.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Round.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Rounddown.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Roundup.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Row.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sign.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sin.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sinh.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Small.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sqrt.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Stdev.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sum.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumproduct.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumsq.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumx2my2.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumx2py2.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumxmy2.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/T.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Tan.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Tanh.java
src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Upper.java
src/scratchpad/src/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java
src/scratchpad/testcases/org/apache/poi/hssf/data/FormulaEvalTestData.xls
src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/GenericFormulaTestCase.java
src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestEverything.java

index 24d012577ad17545cec8c14c94e02b5785e75266..4f121ab0c2abc557cccf5db266c084b1b1283133 100644 (file)
@@ -676,8 +676,8 @@ public abstract class AbstractFunctionPtg extends OperationPtg {
         functionData[209][0]=new Byte(Ptg.CLASS_VALUE);functionData[209][1]=new byte[] {Ptg.CLASS_VALUE};functionData[209][2]=new Integer(2);
         functionData[210][0]=new Byte(Ptg.CLASS_VALUE);functionData[210][1]=new byte[] {Ptg.CLASS_VALUE};functionData[210][2]=new Integer(2);
         functionData[211][0]=new Byte(Ptg.CLASS_VALUE);functionData[211][1]=new byte[] {Ptg.CLASS_VALUE};functionData[211][2]=new Integer(1);
-        functionData[212][0]=new Byte(Ptg.CLASS_VALUE);functionData[212][1]=new byte[] {Ptg.CLASS_VALUE};functionData[212][2]=new Integer(1);
-        functionData[213][0]=new Byte(Ptg.CLASS_VALUE);functionData[213][1]=new byte[] {Ptg.CLASS_REF};functionData[213][2]=new Integer(-1);
+        functionData[212][0]=new Byte(Ptg.CLASS_VALUE);functionData[212][1]=new byte[] {Ptg.CLASS_VALUE};functionData[212][2]=new Integer(2);
+        functionData[213][0]=new Byte(Ptg.CLASS_VALUE);functionData[213][1]=new byte[] {Ptg.CLASS_REF};functionData[213][2]=new Integer(2);
         functionData[214][0]=new Byte(Ptg.CLASS_VALUE);functionData[214][1]=new byte[] {Ptg.CLASS_VALUE};functionData[214][2]=new Integer(-1);
         
         
index bc993a662f9f845b6870a8965c45b1e1c30b9cbf..0947659c397f545b7bc084776c06666d2efbcf88 100644 (file)
@@ -31,6 +31,7 @@ public class AddEval extends NumericOperationEval {
                 | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
                 | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
                 | ValueEvalToNumericXlator.STRING_IS_PARSED
+                | ValueEvalToNumericXlator.REF_STRING_IS_PARSED
                 ));
 
     public AddEval(Ptg ptg) {
index 3b9d193bc119d56fbd492c696b2f40c9c6772b85..38803c96899e8e6379fff1c7ca925af8c9c8c645 100644 (file)
@@ -22,6 +22,7 @@ public class DivideEval extends NumericOperationEval {
                 | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
                 | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
                 | ValueEvalToNumericXlator.STRING_IS_PARSED
+                | ValueEvalToNumericXlator.REF_STRING_IS_PARSED
                 ));
 
     public DivideEval(Ptg ptg) {
index e1c8a7fcc097cf01bacd4e9e02d79d2eeb1e5785..a32db96863d495d36703c41596f1fb77924e2f5f 100644 (file)
@@ -7,576 +7,15 @@ package org.apache.poi.hssf.record.formula.eval;
 /**
  * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  * 
- * Error code reference from OpenOffice documentation: <br/><TABLE WIDTH=575
- * BORDER=1 CELLPADDING=2 CELLSPACING=0 BGCOLOR="#ffffff"> <COL WIDTH=42> <COL
- * WIDTH=118> <COL WIDTH=401>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="tablehead" ALIGN=LEFT>
- * Error Code
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="tablehead" ALIGN=LEFT>
- * Message
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="tablehead" ALIGN=LEFT>
- * Explanation
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 501
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Invalid character
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Character in a formula is not valid, for example, &quot;=1Eq&quot; instead of
- * &quot;=1E2&quot;.
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 502
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Invalid argument
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Function argument is not valid, for example, a negative number for the root
- * function.
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 503
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Invalid floating point operation
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Division by 0, or another calculation that results in an overflow of the
- * defined value range.
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 504
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Parameter list error
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Function parameter is not valid, for example, text instead of a number, or a
- * domain reference instead of cell reference.
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 505
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Internal syntax error
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Not used
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 506
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Invalid semicolon
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Not used
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 507
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Error: Pair missing
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Not used
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 508
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Error: Pair missing
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Missing bracket, for example, closing brackets, but no opening brackets
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 509
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Missing operator
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Operator is missing, for example, &quot;=2(3+4) * &quot;, where the operator
- * between &quot;2&quot; and &quot;(&quot; is missing.
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 510
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Missing variable
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Variable is missing, for example when two operators are together
- * &quot;=1+*2&quot;.
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 511
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Missing variable
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Function requires more variables than are provided, for example, AND() and
- * OR().
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 512
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Formula overflow
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * <B>Compiler: </B> the total number of internal tokens, (that is, operators,
- * variables, brackets) in the formula exceeds 512. <B>Interpreter: </B> the
- * total number of matrices that the formula creates exceeds 150. This includes
- * basic functions that receive too large an array as a parameter (max. 0xFFFE,
- * for example, 65534 bytes).
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 513
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * String overflow
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * <B>Compiler: </B> an identifier in the formula exceeds 64 KB in size.
- * <B>Interpreter: </B> a result of a string operation exceeds 64 KB in size.
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 514
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Internal overflow
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Sort operation attempted on too much numerical data (max. 100000) or a
- * calculation stack overflow.
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 515
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Internal syntax error
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Not used
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 516
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Internal syntax error
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Matrix is expected on the calculation stack, but is not available.
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 517
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Internal syntax error
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Unknown code, for example, a document with a newer function is loaded in an
- * older version that does not contain the function.
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 518
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Internal syntax error
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Variable is not available
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 519
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * No result (#VALUE is in the cell rather than Err:519!)
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Formula yields a value that does not corresponds to the definition, or a cell
- * that is referenced in the formula contains text instead of a number.
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 520
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Internal syntax error
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Compiler creates an unknown compiler code.
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 521
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Internal syntax error
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * No result.
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 522
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Circular reference
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Formula refers directly or indirectly to itself and the iterations option is
- * not selected under Tools - Options - Table Document - Calculate.
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 523
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * The calculation procedure does not converge
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Financial statistics function missed a targeted value or iterations of
- * circular references do not reach the minimum change within the maximum steps
- * that are set.
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 524
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * <A NAME="kw66944_5"> </A><A NAME="kw66944_4"> </A> invalid references
- * (instead of Err:524 cell contains #REF)
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * <B>Compiler: </B> a column or row description name could not be resolved.
- * <B>Interpreter: </B> in a formula, the column, row, or sheet that contains a
- * referenced cell is missing.
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 525
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * <A NAME="kw66944_3"> </A><A NAME="kw66944_2"> </A> invalid names (instead of
- * Err:525 cell contains #NAME?)
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * An identifier could not be evaluated, for example, no valid reference, no
- * valid domain name, no column/row label, no macro, incorrect decimal divider,
- * add-in not found.
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 526
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Internal syntax error
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Obsolete, no longer used, but could come from old documents if the result is
- * a formula from a domain.
- * </P>
- * </TD>
- * </TR>
- * <TR VALIGN=TOP>
- * <TD WIDTH=42 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * 527
- * </P>
- * </TD>
- * <TD WIDTH=118 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * Internal overflow
- * </P>
- * </TD>
- * <TD WIDTH=401 BGCOLOR="#ffffff">
- * <P CLASS="textintable" ALIGN=LEFT>
- * <B>Interpreter: </B>References, such as when a cell references a cell, are
- * too encapsulated.
- * </P>
- * </TD>
- * </TR>
- * </TABLE>
- *  
  */
 public class ErrorEval implements ValueEval {
 
     private int errorCode;
 
-    // Oo std error codes
-    public static final ErrorEval ERROR_501 = new ErrorEval(501);
 
-    public static final ErrorEval ERROR_502 = new ErrorEval(502);
+    public static final ErrorEval NAME_INVALID = new ErrorEval(525);
 
-    public static final ErrorEval ERROR_503 = new ErrorEval(503);
-
-    public static final ErrorEval ERROR_504 = new ErrorEval(504);
-
-    public static final ErrorEval ERROR_505 = new ErrorEval(505);
-
-    public static final ErrorEval ERROR_506 = new ErrorEval(506);
-
-    public static final ErrorEval ERROR_507 = new ErrorEval(507);
-
-    public static final ErrorEval ERROR_508 = new ErrorEval(508);
-
-    public static final ErrorEval ERROR_509 = new ErrorEval(509);
-
-    public static final ErrorEval ERROR_510 = new ErrorEval(510);
-
-    public static final ErrorEval ERROR_511 = new ErrorEval(511);
-
-    public static final ErrorEval ERROR_512 = new ErrorEval(512);
-
-    public static final ErrorEval ERROR_513 = new ErrorEval(513);
-
-    public static final ErrorEval ERROR_514 = new ErrorEval(514);
-
-    public static final ErrorEval ERROR_515 = new ErrorEval(515);
-
-    public static final ErrorEval ERROR_516 = new ErrorEval(516);
-
-    public static final ErrorEval ERROR_517 = new ErrorEval(517);
-
-    public static final ErrorEval ERROR_518 = new ErrorEval(518);
-
-    public static final ErrorEval ERROR_519 = new ErrorEval(519);
-
-    public static final ErrorEval ERROR_520 = new ErrorEval(520);
-
-    public static final ErrorEval ERROR_521 = new ErrorEval(521);
-
-    public static final ErrorEval ERROR_522 = new ErrorEval(522);
-
-    public static final ErrorEval ERROR_523 = new ErrorEval(523);
-
-    public static final ErrorEval ERROR_524 = new ErrorEval(524);
-
-    public static final ErrorEval ERROR_525 = new ErrorEval(525);
-
-    public static final ErrorEval ERROR_526 = new ErrorEval(526);
-
-    public static final ErrorEval ERROR_527 = new ErrorEval(527);
-
-    public static final ErrorEval NAME_INVALID = ERROR_525;
-
-    public static final ErrorEval VALUE_INVALID = ERROR_519;
+    public static final ErrorEval VALUE_INVALID = new ErrorEval(519);
 
     
     // Non std error codes
index e55d53226a090e58a2fe885b1abf7f66c048a212..bd4d0c539ad7b8e60d7e83a1b713bc4e7d89a655 100644 (file)
@@ -22,6 +22,7 @@ public class MultiplyEval extends NumericOperationEval {
                 | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
                 | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
                 | ValueEvalToNumericXlator.STRING_IS_PARSED
+                | ValueEvalToNumericXlator.REF_STRING_IS_PARSED
                 ));
 
     public MultiplyEval(Ptg ptg) {
index 764c59f20534318799d08b1acfe449587f63a780..9ca0d746858abe7130260534c07d61a2b53c9872 100644 (file)
@@ -13,6 +13,8 @@ import org.apache.poi.hssf.record.formula.Ptg;
  *  
  */
 public class NumberEval implements NumericValueEval, StringValueEval {
+    
+    public static final NumberEval ZERO = new NumberEval(0);
 
     private double value;
     private String stringValue;
index 641cf10ae63ade349feef3ad04dd522908754ea6..ef34d21f5f3ced63cce15bd4b2867f6dfde40965 100644 (file)
@@ -22,6 +22,7 @@ public class PowerEval extends NumericOperationEval {
                 | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
                 | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
                 | ValueEvalToNumericXlator.STRING_IS_PARSED
+                | ValueEvalToNumericXlator.REF_STRING_IS_PARSED
                 ));
 
     public PowerEval(Ptg ptg) {
index de5004d92dff3687f0385812231e46e849bea6cd..b07f70879a5a312c687701268804d9db042f0505 100644 (file)
@@ -38,7 +38,7 @@ public abstract class RelationalOperationEval implements OperationEval {
         
         switch (operands.length) {
         default:
-            retval.ee = ErrorEval.ERROR_520;
+            retval.ee = ErrorEval.VALUE_INVALID;
             break;
         case 2:
             internalDoEvaluate(operands, srcRow, srcCol, retval, 0);
index f8b4cca00d06a58c2d322e64a2bca105d23cb395..9f7869c9adc578200c0ada299e5420347528afd1 100644 (file)
@@ -13,6 +13,8 @@ import org.apache.poi.hssf.record.formula.StringPtg;
  */
 public class StringEval implements StringValueEval {
 
+    public static final StringEval EMPTY_INSTANCE = new StringEval("");
+    
     private String value;
 
     public StringEval(Ptg ptg) {
index 6b2c9899cfe24a728a6b7fd88f03126c4afdf6e7..8b8208db6414d213599b06b8537389ef1c7630b9 100644 (file)
@@ -22,6 +22,7 @@ public class SubtractEval extends NumericOperationEval {
                 | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
                 | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
                 | ValueEvalToNumericXlator.STRING_IS_PARSED
+                | ValueEvalToNumericXlator.REF_STRING_IS_PARSED
                 ));
 
     public SubtractEval(Ptg ptg) {
index 84eececceb5ec16b3ebf92f7d9614261c90439ab..793290a04a53a6685547e1df7248170670ca26e9 100644 (file)
@@ -21,6 +21,7 @@ public class UnaryMinusEval extends NumericOperationEval {
                 | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
                 | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
                 | ValueEvalToNumericXlator.STRING_IS_PARSED
+                | ValueEvalToNumericXlator.REF_STRING_IS_PARSED
                 ));
 
 
index 5b311661fd3d2bcaa87b3cebd9df6ddc24f08902..556b3f8de8bc8c47e0d92a5ab064eade656b3eb8 100644 (file)
@@ -18,7 +18,7 @@ public class UnaryPlusEval implements OperationEval /*extends NumericOperationEv
     /* 
      * COMMENT FOR COMMENTED CODE IN THIS FILE
      * 
-     * The loser who programmed this in excel didnt care to
+     * In excel the programmer seems to not have cared to
      * think about how strings were handled in other numeric
      * operations when he/she was implementing this operation :P
      * 
@@ -27,10 +27,8 @@ public class UnaryPlusEval implements OperationEval /*extends NumericOperationEv
      * Q. If the formula -"hello" evaluates to #VALUE! in excel, what should
      * the formula +"hello" evaluate to?
      * 
-     * A. +"hello" evaluates to "hello"
+     * A. +"hello" evaluates to "hello" (what the...?)
      * 
-     * DO NOT remove the commented code (In memory of the excel
-     * programmer who implemented the UnaryPlus operation :)
      */
 
     
index fb089227e59d20c24b9a6d074acfe5f9914ceb27..3111a42156898bcf927413348822d7b39e2d29a8 100644 (file)
@@ -10,25 +10,33 @@ package org.apache.poi.hssf.record.formula.eval;
  */
 public class ValueEvalToNumericXlator {
 
-    public static final short STRING_IS_PARSED = 0x0001;
-    public static final short BOOL_IS_PARSED = 0x0002;
+    public static final int STRING_IS_PARSED = 0x0001;
+    public static final int BOOL_IS_PARSED = 0x0002;
+    public static final int BLANK_IS_PARSED = 0x0004; // => blanks are not ignored, converted to 0
     
-    public static final short REF_STRING_IS_PARSED = 0x0004;
-    public static final short REF_BOOL_IS_PARSED = 0x0008;
+    public static final int REF_STRING_IS_PARSED = 0x0008;
+    public static final int REF_BOOL_IS_PARSED = 0x0010;
+    public static final int REF_BLANK_IS_PARSED = 0x0020;
     
-    public static final short EVALUATED_REF_STRING_IS_PARSED = 0x0010;
-    public static final short EVALUATED_REF_BOOL_IS_PARSED = 0x0020;
+    public static final int EVALUATED_REF_STRING_IS_PARSED = 0x0040;
+    public static final int EVALUATED_REF_BOOL_IS_PARSED = 0x0080;
+    public static final int EVALUATED_REF_BLANK_IS_PARSED = 0x0100;
     
-    public static final short STRING_TO_BOOL_IS_PARSED = 0x0040;
-    public static final short REF_STRING_TO_BOOL_IS_PARSED = 0x0080;
+    public static final int STRING_TO_BOOL_IS_PARSED = 0x0200;
+    public static final int REF_STRING_TO_BOOL_IS_PARSED = 0x0400;
     
-    public static final short STRING_IS_INVALID_VALUE = 0x0100;
-    public static final short REF_STRING_IS_INVALID_VALUE = 0x200;
+    public static final int STRING_IS_INVALID_VALUE = 0x0800;
+    public static final int REF_STRING_IS_INVALID_VALUE = 0x1000;
     
-    private final short flags;
+//    public static final int BOOL_IS_BLANK = 0x2000;
+//    public static final int REF_BOOL_IS_BLANK = 0x4000;
+//    public static final int STRING_IS_BLANK = 0x8000;
+//    public static final int REF_STRING_IS_BLANK = 0x10000;
     
+    private final int flags;
     
-    public ValueEvalToNumericXlator(short flags) {
+    
+    public ValueEvalToNumericXlator(int flags) {
         this.flags = flags;
     }
     
@@ -52,23 +60,20 @@ public class ValueEvalToNumericXlator {
         }
         
         // booleval
-        else if (((flags | BOOL_IS_PARSED) > 0) && eval instanceof BoolEval) {
-            retval = (NumericValueEval) eval;
+        else if (eval instanceof BoolEval) {
+            retval = ((flags & BOOL_IS_PARSED) > 0)
+                ? (NumericValueEval) eval
+                : xlateBlankEval(BLANK_IS_PARSED);
         } 
         
         // stringeval 
         else if (eval instanceof StringEval) {
-            retval = handleStringEval((StringEval) eval);
+            retval = xlateStringEval((StringEval) eval); // TODO: recursive call needed
         }
         
         // refeval
         else if (eval instanceof RefEval) {
-            retval = handleRefEval((RefEval) eval);
-        }
-        
-        //blankeval
-        else if (eval instanceof BlankEval) {
-            retval = eval;
+            retval = xlateRefEval((RefEval) eval);
         }
         
         // erroreval
@@ -76,40 +81,55 @@ public class ValueEvalToNumericXlator {
             retval = eval;
         }
         
+        else if (eval instanceof BlankEval) {
+            retval = xlateBlankEval(BLANK_IS_PARSED);
+        }
+        
         // probably AreaEval? then not acceptable.
         else {
             throw new RuntimeException("Invalid ValueEval type passed for conversion: " + eval.getClass());
         }
+        
         return retval;
     }
     
+    /**
+     * no args are required since BlankEval has only one 
+     * instance. If flag is set, a zero
+     * valued numbereval is returned, else BlankEval.INSTANCE
+     * is returned.
+     * @return
+     */
+    private ValueEval xlateBlankEval(int flag) {
+        return ((flags & flag) > 0)
+                ? (ValueEval) NumberEval.ZERO
+                : BlankEval.INSTANCE;
+    }
+    
     /**
      * uses the relevant flags to decode the supplied RefVal
      * @param eval
      * @return
      */
-    private ValueEval handleRefEval(RefEval reval) {
+    private ValueEval xlateRefEval(RefEval reval) {
         ValueEval retval = null;
         ValueEval eval = (ValueEval) reval.getInnerValueEval();
         
         // most common case - least worries :)
         if (eval instanceof NumberEval) {
-            retval = (NumberEval) eval; // the cast is correct :)
+            retval = (NumberEval) eval;
         }
         
         // booleval
-        else if (((flags | REF_BOOL_IS_PARSED) > 0) && eval instanceof BoolEval) {
-            retval = (NumericValueEval) eval;
+        else if (eval instanceof BoolEval) {
+            retval = ((flags & REF_BOOL_IS_PARSED) > 0)
+                    ? (ValueEval) eval
+                    : BlankEval.INSTANCE;
         } 
         
         // stringeval 
         else if (eval instanceof StringEval) {
-            retval = handleRefStringEval((StringEval) eval);
-        }
-        
-        //blankeval
-        else if (eval instanceof BlankEval) {
-            retval = eval;
+            retval = xlateRefStringEval((StringEval) eval);
         }
         
         // erroreval
@@ -117,10 +137,24 @@ public class ValueEvalToNumericXlator {
             retval = eval;
         }
         
-        // probably AreaEval or another RefEval? then not acceptable.
-        else {
+        // refeval
+        else if (eval instanceof RefEval) {
+            RefEval re = (RefEval) eval;
+            retval = xlateRefEval(re);
+        }
+        
+        else if (eval instanceof BlankEval) {
+            retval = xlateBlankEval(reval.isEvaluated() ? EVALUATED_REF_BLANK_IS_PARSED : REF_BLANK_IS_PARSED);
+        }
+        
+        // probably AreaEval ? then not acceptable.
+        else { 
             throw new RuntimeException("Invalid ValueEval type passed for conversion: " + eval.getClass());
         }
+
+        
+        
+
         return retval;
     }
     
@@ -129,20 +163,29 @@ public class ValueEvalToNumericXlator {
      * @param eval
      * @return
      */
-    private ValueEval handleStringEval(StringEval eval) {
+    private ValueEval xlateStringEval(StringEval eval) {
         ValueEval retval = null;
-        if ((flags | STRING_IS_PARSED) > 0) {
-            StringEval sve = (StringEval) eval;
-            String s = sve.getStringValue();
+        if ((flags & STRING_IS_PARSED) > 0) {
+            String s = eval.getStringValue();
             try { 
                 double d = Double.parseDouble(s);
                 retval = new NumberEval(d);
             } 
-            catch (Exception e) { retval = ErrorEval.VALUE_INVALID; }
+            catch (Exception e) {
+                if ((flags & STRING_TO_BOOL_IS_PARSED) > 0) {
+                    try { 
+                        boolean b = Boolean.getBoolean(s);
+                        retval = b ? BoolEval.TRUE : BoolEval.FALSE;
+                    } 
+                    catch (Exception e2) { retval = ErrorEval.VALUE_INVALID; }
+                }
+                else {
+                    retval = ErrorEval.VALUE_INVALID;
+                }
+            }
         }
-        else if ((flags | STRING_TO_BOOL_IS_PARSED) > 0) {
-            StringEval sve = (StringEval) eval;
-            String s = sve.getStringValue();
+        else if ((flags & STRING_TO_BOOL_IS_PARSED) > 0) {
+            String s = eval.getStringValue();
             try { 
                 boolean b = Boolean.getBoolean(s);
                 retval = b ? BoolEval.TRUE : BoolEval.FALSE;
@@ -151,13 +194,13 @@ public class ValueEvalToNumericXlator {
         }
         
         // strings are errors?
-        else if ((flags | STRING_IS_INVALID_VALUE) > 0) {
+        else if ((flags & STRING_IS_INVALID_VALUE) > 0) {
             retval = ErrorEval.VALUE_INVALID;
         }
         
         // ignore strings
         else {
-            retval = BlankEval.INSTANCE;
+            retval = xlateBlankEval(BLANK_IS_PARSED);
         }
         return retval;
     }
@@ -167,18 +210,29 @@ public class ValueEvalToNumericXlator {
      * @param eval
      * @return
      */
-    private ValueEval handleRefStringEval(StringEval eval) {
+    private ValueEval xlateRefStringEval(StringEval eval) {
         ValueEval retval = null;
-        if ((flags | REF_STRING_IS_PARSED) > 0) {
+        if ((flags & REF_STRING_IS_PARSED) > 0) {
             StringEval sve = (StringEval) eval;
             String s = sve.getStringValue();
             try { 
                 double d = Double.parseDouble(s);
                 retval = new NumberEval(d);
             } 
-            catch (Exception e) { retval = ErrorEval.VALUE_INVALID; }
+            catch (Exception e) { 
+                if ((flags & REF_STRING_TO_BOOL_IS_PARSED) > 0) {
+                    try { 
+                        boolean b = Boolean.getBoolean(s);
+                        retval = b ? BoolEval.TRUE : BoolEval.FALSE;
+                    } 
+                    catch (Exception e2) { retval = ErrorEval.VALUE_INVALID; }
+                }
+                else {
+                    retval = ErrorEval.VALUE_INVALID;
+                }
+            }
         }
-        else if ((flags | REF_STRING_TO_BOOL_IS_PARSED) > 0) {
+        else if ((flags & REF_STRING_TO_BOOL_IS_PARSED) > 0) {
             StringEval sve = (StringEval) eval;
             String s = sve.getStringValue();
             try { 
@@ -189,11 +243,11 @@ public class ValueEvalToNumericXlator {
         }
         
         // strings are errors?
-        else if ((flags | REF_STRING_IS_INVALID_VALUE) > 0) {
+        else if ((flags & REF_STRING_IS_INVALID_VALUE) > 0) {
             retval = ErrorEval.VALUE_INVALID;
         }
         
-        // ignore strings
+        // strings are blanks
         else {
             retval = BlankEval.INSTANCE;
         }
index 9f29615ae510d5e9616b34a077799acb2fd84d2d..31960a9b924149d5b5731cbc332b991b0b32d3d1 100644 (file)
@@ -10,7 +10,6 @@ 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;
@@ -18,19 +17,6 @@ import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
  */
 public class Abs extends NumericFunction {
     
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
-
     public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
         double d = 0;
         ValueEval retval = null;
@@ -54,7 +40,10 @@ public class Abs extends NumericFunction {
         }
         
         if (retval == null) {
-            retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(Math.abs(d));
+            d = Math.abs(d);
+            retval = (Double.isNaN(d))
+                    ? (ValueEval) ErrorEval.VALUE_INVALID
+                    : new NumberEval(d);
         }
         return retval;
     }
index eb8e69301adabe6a24e372cfd6ca666ac22fb870..dc6030ca9cf3c14d89974204061003bb37dd35a2 100644 (file)
@@ -10,33 +10,20 @@ 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;
- *  
+ *
  */
 public class Acos extends NumericFunction {
-    
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
 
     public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
         double d = 0;
         ValueEval retval = null;
-        
+
         switch (operands.length) {
         default:
+            retval = ErrorEval.VALUE_INVALID;
             break;
         case 1:
             ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
@@ -51,10 +38,12 @@ public class Acos extends NumericFunction {
                 retval = ErrorEval.NUM_ERROR;
             }
         }
-        
+
         if (retval == null) {
             d = Math.acos(d);
-            retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
+            retval = (Double.isNaN(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
         }
         return retval;
     }
index 570e109325a36e25203c733a78852c7cbc233958..1ff637071e36b10d2395816b319cd9aee3b160f8 100644 (file)
@@ -9,38 +9,25 @@ 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;
- * Support for hyperbolic trig functions was added as a part of 
- * Java distribution only in JDK1.5. This class uses custom 
+ * Support for hyperbolic trig functions was added as a part of
+ * Java distribution only in JDK1.5. This class uses custom
  * naive implementation based on formulas at:
  * http://www.math2.org/math/trig/hyperbolics.htm
  * These formulas seem to agree with excel's implementation.
- * 
+ *
  */
 public class Acosh extends NumericFunction {
-    
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
 
     public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
         double d = 0;
         ValueEval retval = null;
-        
+
         switch (operands.length) {
         default:
+            retval = ErrorEval.VALUE_INVALID;
             break;
         case 1:
             ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
@@ -49,10 +36,12 @@ public class Acosh extends NumericFunction {
                 d = ne.getNumberValue();
             }
         }
-        
+
         if (retval == null) {
-            d = Math.log(Math.sqrt(Math.pow(d, 2) - 1) + d);
-            retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.NUM_ERROR : new NumberEval(d);
+            d = MathX.acosh(d);
+            retval = (Double.isNaN(d) || Double.isInfinite(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
         }
         return retval;
     }
index ebf169b93c60e9dee9a54a7e24ba15ccf29c31ca..a4e005e91f5e64710ac6348398e0c7eee0d35a9d 100644 (file)
@@ -10,33 +10,20 @@ 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;
- *  
+ *
  */
 public class Asin extends NumericFunction {
-    
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
 
     public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
         double d = 0;
         ValueEval retval = null;
-        
+
         switch (operands.length) {
         default:
+            retval = ErrorEval.VALUE_INVALID;
             break;
         case 1:
             ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
@@ -51,10 +38,12 @@ public class Asin extends NumericFunction {
                 retval = ErrorEval.NUM_ERROR;
             }
         }
-        
+
         if (retval == null) {
             d = Math.asin(d);
-            retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
+            retval = (Double.isNaN(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
         }
         return retval;
     }
index b33f12c724cb008e7a886edca682ff91ae2e5343..12c7bdc063643b85ad608db12d1db2da54b1c68d 100644 (file)
@@ -10,38 +10,26 @@ 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;
- * Support for hyperbolic trig functions was added as a part of 
- * Java distribution only in JDK1.5. This class uses custom 
+ * Support for hyperbolic trig functions was added as a part of
+ * Java distribution only in JDK1.5. This class uses custom
  * naive implementation based on formulas at:
  * http://www.math2.org/math/trig/hyperbolics.htm
  * These formulas seem to agree with excel's implementation.
- * 
+ *
  */
 public class Asinh extends NumericFunction {
-    
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
 
+    
     public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
         double d = 0;
         ValueEval retval = null;
-        
+
         switch (operands.length) {
         default:
+            retval = ErrorEval.VALUE_INVALID;
             break;
         case 1:
             ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
@@ -56,9 +44,9 @@ public class Asinh extends NumericFunction {
                 retval = ErrorEval.NUM_ERROR;
             }
         }
-        
+
         if (retval == null) {
-            d = Math.log(Math.sqrt(Math.pow(d, 2) + 1) + d);
+            d = MathX.asinh(d);
             retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.NUM_ERROR : new NumberEval(d);
         }
         return retval;
index a156c0f2d6a61a21ca55ae9094ca4b77283cd9b8..6fcc9c3c28079c1e00f03c779b8ed9d3bdd9b835 100644 (file)
@@ -10,33 +10,20 @@ 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;
- *  
+ *
  */
 public class Atan extends NumericFunction {
-    
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
 
     public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
         double d = 0;
         ValueEval retval = null;
-        
+
         switch (operands.length) {
         default:
+            retval = ErrorEval.VALUE_INVALID;
             break;
         case 1:
             ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
@@ -51,10 +38,12 @@ public class Atan extends NumericFunction {
                 retval = ErrorEval.NUM_ERROR;
             }
         }
-        
+
         if (retval == null) {
             d = Math.atan(d);
-            retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
+            retval = (Double.isNaN(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
         }
         return retval;
     }
index 89e6b09041f2da005ccbd33268190e4875b43b55..fa1afbf420240d4f87c9773e554a70593325dc3d 100644 (file)
@@ -10,34 +10,21 @@ 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;
- *  
+ *
  */
 public class Atan2 extends NumericFunction {
-    
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
 
     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);
@@ -51,7 +38,7 @@ public class Atan2 extends NumericFunction {
             else {
                 retval = ErrorEval.NUM_ERROR;
             }
-            
+
             if (retval == null) {
                 ve = singleOperandEvaluate(operands[1], srcRow, srcCol);
                 if (ve instanceof NumericValueEval) {
@@ -66,10 +53,14 @@ public class Atan2 extends NumericFunction {
                 }
             }
         }
-        
+
         if (retval == null) {
-            double d = (d0 == d1 && d1 == 0) ? Double.NaN : Math.atan2(d1, d0);
-            retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
+            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;
     }
index 7049185414f715c9074b62ac9d0b750f77ad43df..a17a9aff50b6313d027b82ff0087008077f6d0e3 100644 (file)
@@ -10,38 +10,25 @@ 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;
- * Support for hyperbolic trig functions was added as a part of 
- * Java distribution only in JDK1.5. This class uses custom 
+ * Support for hyperbolic trig functions was added as a part of
+ * Java distribution only in JDK1.5. This class uses custom
  * naive implementation based on formulas at:
  * http://www.math2.org/math/trig/hyperbolics.htm
  * These formulas seem to agree with excel's implementation.
- * 
+ *
  */
 public class Atanh extends NumericFunction {
-    
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
 
     public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
         double d = 0;
         ValueEval retval = null;
-        
+
         switch (operands.length) {
         default:
+            retval = ErrorEval.VALUE_INVALID;
             break;
         case 1:
             ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
@@ -56,9 +43,9 @@ public class Atanh extends NumericFunction {
                 retval = ErrorEval.NUM_ERROR;
             }
         }
-        
+
         if (retval == null) {
-            d = Math.log((1 + d)/(1 - d)) / 2;
+            d = MathX.atanh(d);
             retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.NUM_ERROR : new NumberEval(d);
         }
         return retval;
index 850e40e3fd0652200703dcab07fd07f5b4f11e07..98e5bd70b863cba4e810e12c682a13f668b52046 100644 (file)
@@ -4,10 +4,58 @@
  */
 package org.apache.poi.hssf.record.formula.functions;
 
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  *
  */
-public class Avedev extends DefaultFunctionImpl {
+public class Avedev extends MultiOperandNumericFunction {
+
+    private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
+        new ValueEvalToNumericXlator((short) (0
+              //    ValueEvalToNumericXlator.BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
+                | ValueEvalToNumericXlator.STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE
+                | ValueEvalToNumericXlator.EVALUATED_REF_BLANK_IS_PARSED
+                ));
+    
+    /**
+     * this is the default impl for the factory method getXlator
+     * of the super class NumericFunction. Subclasses can override this method
+     * if they desire to return a different ValueEvalToNumericXlator instance
+     * than the default.
+     */
+    protected ValueEvalToNumericXlator getXlator() {
+        return DEFAULT_NUM_XLATOR;
+    }
 
+    
+    
+    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        double[] values = getNumberArray(operands, srcCellRow, srcCellCol);
+        if (values == null) {
+            retval = ErrorEval.VALUE_INVALID;
+        }
+        else {
+            double d = StatsLib.avedev(values);
+            retval = (Double.isNaN(d) || Double.isInfinite(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
+        }
+        
+        return retval;
+    }
 }
index 90accd5cc4b0b8082f534c82bc3851b38c339884..879ba78296deef2a28d7e97aea35da4b9f34850d 100644 (file)
@@ -4,10 +4,58 @@
  */
 package org.apache.poi.hssf.record.formula.functions;
 
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  *
  */
-public class Average extends DefaultFunctionImpl {
+public class Average extends MultiOperandNumericFunction {
+
+    private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
+        new ValueEvalToNumericXlator((short) (0
+              //    ValueEvalToNumericXlator.BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
+                | ValueEvalToNumericXlator.STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE
+                | ValueEvalToNumericXlator.EVALUATED_REF_BLANK_IS_PARSED
+                ));
+    
+    /**
+     * this is the default impl for the factory method getXlator
+     * of the super class NumericFunction. Subclasses can override this method
+     * if they desire to return a different ValueEvalToNumericXlator instance
+     * than the default.
+     */
+    protected ValueEvalToNumericXlator getXlator() {
+        return DEFAULT_NUM_XLATOR;
+    }
 
+    
+    
+    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        double[] values = getNumberArray(operands, srcCellRow, srcCellCol);
+        if (values == null) {
+            retval = ErrorEval.VALUE_INVALID;
+        }
+        else {
+            double d = MathX.average(values);
+            retval = (Double.isNaN(d) || Double.isInfinite(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
+        }
+        
+        return retval;
+    }
 }
index 719b1b6689a0b25e92053903ad54c3c20db5371f..d87194ed1b4d309ec7cfba9eb521603e4354f86e 100644 (file)
@@ -4,10 +4,10 @@
  */
 package org.apache.poi.hssf.record.formula.functions;
 
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt; 
  *
  */
 public class Averagea extends DefaultFunctionImpl {
-
 }
index ee73137854a3c44b4114a43e487724b2d2cab534..64ba6123622837b9eeaabb582a5380dd6d5c948f 100644 (file)
@@ -1,14 +1,66 @@
 /*
- * Created on May 6, 2005
+ * 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 
- *  
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
+ *
  */
-public class Ceiling extends DefaultFunctionImpl {
-    
+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;
+    }
+
 }
index fa04a3ce0bebe540b2451ae201d2fd647eeb772a..0bf4b7279df4813bc00fba6f5bf80f2da3689472 100644 (file)
@@ -4,10 +4,50 @@
  */
 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.ValueEval;
+
 /**
  * @author 
  *
  */
 public class Column extends DefaultFunctionImpl {
+    public Eval evaluate(Eval[] evals, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        int cnum = -1;
+        
+        switch (evals.length) {
+        default:
+            retval = ErrorEval.VALUE_INVALID;
+        case 1:
+            if (evals[0] instanceof AreaEval) {
+                AreaEval ae = (AreaEval) evals[0];
+                cnum = ae.getFirstColumn();
+            }
+            else if (evals[0] instanceof RefEval) {
+                RefEval re = (RefEval) evals[0];
+                cnum = re.getColumn();
+            }
+            else { // anything else is not valid argument
+                retval = ErrorEval.VALUE_INVALID;
+            }
+            break;
+        case 0:
+            cnum = srcCellCol;
+        }
+        
+        if (retval == null) {
+            retval = (cnum >= 0)
+                    ? new NumberEval(cnum + 1) // +1 since excel colnums are 1 based
+                    : (ValueEval) ErrorEval.VALUE_INVALID;
+        }
+        
+        return retval;
+    }
+    
 
 }
index 1360d9a66f507f1e944e2a7c7ee0e612d6339a1f..82e951090ab3db783b3e51beb7d5336ec9f74551 100644 (file)
@@ -4,10 +4,68 @@
  */
 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 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  *
  */
-public class Combin extends DefaultFunctionImpl {
+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;
+    }
 
 }
index ed920f583cbeb2242653291c7cd3e5b2ce616324..beaa32d4ec39ede0b619acf5f85c4d0c61108033 100644 (file)
@@ -4,10 +4,41 @@
  */
 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.StringEval;
+import org.apache.poi.hssf.record.formula.eval.StringValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  *
  */
-public class Concatenate extends DefaultFunctionImpl {
+public class Concatenate extends TextFunction {
+
 
+    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        StringBuffer sb = new StringBuffer();
+        
+        for (int i=0, iSize=operands.length; i<iSize; i++) {
+            ValueEval ve = singleOperandEvaluate(operands[i], srcCellRow, srcCellCol);
+            if (ve instanceof StringValueEval) {
+                StringValueEval sve = (StringValueEval) ve;
+                sb.append(sve.getStringValue());
+            }
+            else if (ve instanceof BlankEval) {}
+            else {
+                retval = ErrorEval.VALUE_INVALID;
+                break;
+            }
+        }
+        
+        if (retval == null) {
+            retval = new StringEval(sb.toString());
+        }
+        
+        return retval;
+    }
 }
index 52b2c30612052b8cfad9fbb88b7d34ba4f65c2dc..65dce2c0784c474da2e4c39bb8465018de02266f 100644 (file)
@@ -10,33 +10,20 @@ 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;
- *  
+ *
  */
 public class Cos extends NumericFunction {
-    
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
 
     public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
         double d = 0;
         ValueEval retval = null;
-        
+
         switch (operands.length) {
         default:
+            retval = ErrorEval.VALUE_INVALID;
             break;
         case 1:
             ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
@@ -51,7 +38,7 @@ public class Cos extends NumericFunction {
                 retval = ErrorEval.NUM_ERROR;
             }
         }
-        
+
         if (retval == null) {
             d = Math.cos(d);
             retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
index 8956a290671d703e7f2d4488fc536667f0117545..b3ea87ad6dac231b8efbfd5f1da37f8a0464f35c 100644 (file)
@@ -10,33 +10,20 @@ 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;
- *  
+ *
  */
 public class Cosh extends NumericFunction {
-    
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
 
     public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
         double d = 0;
         ValueEval retval = null;
-        
+
         switch (operands.length) {
         default:
+            retval = ErrorEval.VALUE_INVALID;
             break;
         case 1:
             ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
@@ -51,11 +38,9 @@ public class Cosh extends NumericFunction {
                 retval = ErrorEval.NUM_ERROR;
             }
         }
-        
+
         if (retval == null) {
-            double ePowX = Math.pow(E, d);
-            double ePowNegX = Math.pow(E, -d);
-            d = (ePowX + ePowNegX) / 2;
+            d = MathX.cosh(d);
             retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
         }
         return retval;
index 19485af41735f3825146f3ba1aafc7dd58ba9aeb..8dc73e3721a1bade752bdfe8fca06dba9416fc8f 100644 (file)
@@ -10,7 +10,6 @@ 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;
@@ -18,19 +17,6 @@ import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
  */
 public class Degrees extends NumericFunction {
     
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
-
     public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
         double d = 0;
         ValueEval retval = null;
index 74d56b276f80125314c1798c4fc191d79dbe5cbb..301e593bec36ca178164c168ad01af2e34980f01 100644 (file)
@@ -4,10 +4,58 @@
  */
 package org.apache.poi.hssf.record.formula.functions;
 
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  *
  */
-public class Devsq extends DefaultFunctionImpl {
+public class Devsq extends MultiOperandNumericFunction {
+
+    private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
+        new ValueEvalToNumericXlator((short) (0
+                | ValueEvalToNumericXlator.BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
+                | ValueEvalToNumericXlator.STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE
+              //| ValueEvalToNumericXlator.EVALUATED_REF_BLANK_IS_PARSED
+                ));
+    
+    /**
+     * this is the default impl for the factory method getXlator
+     * of the super class NumericFunction. Subclasses can override this method
+     * if they desire to return a different ValueEvalToNumericXlator instance
+     * than the default.
+     */
+    protected ValueEvalToNumericXlator getXlator() {
+        return DEFAULT_NUM_XLATOR;
+    }
 
+    
+    
+    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        double[] values = getNumberArray(operands, srcCellRow, srcCellCol);
+        if (values == null) {
+            retval = ErrorEval.VALUE_INVALID;
+        }
+        else {
+            double d = StatsLib.devsq(values);
+            retval = (Double.isNaN(d) || Double.isInfinite(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
+        }
+        
+        return retval;
+    }
 }
index 7fa2fe79568dcfa8616955b90bb7902b0bcc1535..f32e49a10aa6d92627044500a51390051147067b 100644 (file)
@@ -10,33 +10,20 @@ 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;
- *  
+ *
  */
 public class Dollar extends NumericFunction {
-    
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
 
     public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
         double d = 0;
         ValueEval retval = null;
-        
+
         switch (operands.length) {
         default:
+            retval = ErrorEval.VALUE_INVALID;
             break;
         case 1:
             ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
@@ -51,7 +38,7 @@ public class Dollar extends NumericFunction {
                 retval = ErrorEval.NUM_ERROR;
             }
         }
-        
+
         if (retval == null) {
             retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
         }
index 1d5f2be3645b2103a2bd99ac1f3255cd1eef8bc5..66af342bfdc349d3e4bf641b7bc347a620f5c2ff 100644 (file)
@@ -10,26 +10,12 @@ 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;
  *  
  */
 public class Even extends NumericFunction {
-    
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
 
     public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
         double d = 0;
index e4d1c3ae13fd75eb1df05d09fb1182610410a15e..daa789ed21ae32c62bf27fc6f96794009373fc15 100644 (file)
@@ -4,10 +4,65 @@
  */
 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.BoolEval;
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.StringEval;
+import org.apache.poi.hssf.record.formula.eval.StringValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  *
  */
-public class Exact extends DefaultFunctionImpl {
+public class Exact extends TextFunction {
+
+
+    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        String s0 = null;
+        String s1 = null;
+        
+        switch (operands.length) {
+        default:
+            retval = ErrorEval.VALUE_INVALID;
+            break;
+        case 2:
+            ValueEval ve = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol);
+            if (ve instanceof StringValueEval) {
+                StringValueEval sve = (StringValueEval) ve;
+                s0 = sve.getStringValue();
+            }
+            else if (ve instanceof BlankEval) {
+                s0 = StringEval.EMPTY_INSTANCE.getStringValue();
+            }
+            else {
+                retval = ErrorEval.VALUE_INVALID;
+                break;
+            }
 
+            if (retval == null) {
+                ve = singleOperandEvaluate(operands[1], srcCellRow, srcCellCol);
+                if (ve instanceof StringValueEval) {
+                    StringValueEval sve = (StringValueEval) ve;
+                    s1 = sve.getStringValue();
+                }
+                else if (ve instanceof BlankEval) {
+                    s1 = StringEval.EMPTY_INSTANCE.getStringValue();
+                }
+                else {
+                    retval = ErrorEval.VALUE_INVALID;
+                    break;
+                }
+            }
+        }
+        
+        if (retval == null) {
+            boolean b = s0.equals(s1);
+            retval = b ? BoolEval.TRUE : BoolEval.FALSE;
+        }
+        
+        return retval;
+    }
 }
index 01d7979ec0d258bc408fb83e963ed6c68bcc3470..4b48971675cae0cd94a1daf1807d2a2dff5561e5 100644 (file)
@@ -10,33 +10,20 @@ 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;
- *  
+ *
  */
 public class Exp extends NumericFunction {
-    
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
 
     public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
         double d = 0;
         ValueEval retval = null;
-        
+
         switch (operands.length) {
         default:
+            retval = ErrorEval.VALUE_INVALID;
             break;
         case 1:
             ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
@@ -51,7 +38,7 @@ public class Exp extends NumericFunction {
                 retval = ErrorEval.NUM_ERROR;
             }
         }
-        
+
         if (retval == null) {
             d = Math.pow(E, d);
             retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
index cb28ed1661be5de4246932942515f823322fdc0c..0508e2fd275759371c437e7ffda0e97e33582ab4 100644 (file)
@@ -1,13 +1,58 @@
 /*
- * Created on May 15, 2005
+ * Created on May 22, 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 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  *
  */
-public class Fact extends DefaultFunctionImpl {
+public class Fact extends NumericFunction {
+
+    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
+        double d = 0;
+        ValueEval retval = null;
+
+        switch (operands.length) {
+        default:
+            retval = ErrorEval.VALUE_INVALID;
+            break;
+        case 1:
+            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
+            if (ve instanceof NumericValueEval) {
+                NumericValueEval ne = (NumericValueEval) ve;
+                d = ne.getNumberValue();
+            }
+            else if (ve instanceof BlankEval) {
+                // do nothing
+            }
+            else {
+                retval = ErrorEval.NUM_ERROR;
+            }
+        }
+
+        if (retval == null) {
+            if (d < Integer.MAX_VALUE && d >= 0) {
+                d = MathX.factorial((int) d);
+                retval = (Double.isNaN(d))
+                ? (ValueEval) ErrorEval.VALUE_INVALID
+                : (Double.isInfinite(d))
+                        ? (ValueEval) ErrorEval.NUM_ERROR
+                        : new NumberEval(d);
+            }
+            else {
+                retval = ErrorEval.NUM_ERROR;
+            }
+        }
+        return retval;
+    }
 
 }
index 17b9671ab47820f367b522afec6ef304788c28b8..9ce1fff730d85bceb356778d31f311d4ddc4e8b0 100644 (file)
@@ -4,10 +4,63 @@
  */
 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 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  *
  */
-public class Floor extends DefaultFunctionImpl {
+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;
+    }
 
 }
index fb60fc02949f1ecc1739ba5e0d166fcef7d66b22..391139ded84066b91cadbdadb37b0dc07bada7a3 100644 (file)
@@ -10,33 +10,20 @@ 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;
- *  
+ *
  */
 public class Int extends NumericFunction {
-    
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
 
     public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
         double d = 0;
         ValueEval retval = null;
-        
+
         switch (operands.length) {
         default:
+            retval = ErrorEval.VALUE_INVALID;
             break;
         case 1:
             ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
@@ -51,12 +38,14 @@ public class Int extends NumericFunction {
                 retval = ErrorEval.NUM_ERROR;
             }
         }
-        
+
         if (retval == null) {
             if (d < 0) {
                 d = Math.round(d-0.5);
             }
-            retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval((long) d);
+            retval = (Double.isNaN(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval((long) d);
         }
         return retval;
     }
index e3d24e088a6e6e7da47a9e63fa192436f4542031..60da1e61eef3f1c63fa630bcadb0912890549173 100644 (file)
@@ -4,10 +4,77 @@
  */
 package org.apache.poi.hssf.record.formula.functions;
 
+import org.apache.poi.hssf.record.formula.eval.AreaEval;
+import org.apache.poi.hssf.record.formula.eval.BoolEval;
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.RefEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  *
  */
-public class IsError extends DefaultFunctionImpl {
+public class IsError implements Function {
 
+    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        boolean b = false;
+        
+        switch (operands.length) {
+        default:
+            retval = ErrorEval.VALUE_INVALID;
+            break;
+        case 1:
+            if (operands[0] instanceof ErrorEval) {
+                b = true;
+            }
+            else if (operands[0] instanceof AreaEval) {
+                AreaEval ae = (AreaEval) operands[0];
+                if (ae.contains(srcCellRow, srcCellCol)) { // circular ref!
+                    retval = ErrorEval.CIRCULAR_REF_ERROR;
+                }
+                else if (ae.isRow()) {
+                    if (ae.containsColumn(srcCellCol)) {
+                        ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCellCol);
+                        if (ve instanceof RefEval) 
+                            b = ((RefEval) ve).getInnerValueEval() instanceof ErrorEval;
+                        else 
+                            b = (ve instanceof ErrorEval);
+                    }
+                    else {
+                        b = true;
+                    }
+                }
+                else if (ae.isColumn()) {
+                    if (ae.containsRow(srcCellRow)) {
+                        ValueEval ve = ae.getValueAt(srcCellRow, ae.getFirstColumn());
+                        if (ve instanceof RefEval) 
+                            b = ((RefEval) ve).getInnerValueEval() instanceof ErrorEval;
+                        else 
+                            b = (ve instanceof ErrorEval);
+                    }
+                    else {
+                        b = true;
+                    }
+                }
+                else {
+                    b = true;
+                }
+            }
+            else if (operands[0] instanceof RefEval) {
+                b = ((RefEval) operands[0]).getInnerValueEval() instanceof ErrorEval;
+            }
+            else {
+                b = false;
+            }
+        }
+        
+        if (retval == null) {
+            retval = b
+                    ? BoolEval.TRUE
+                    : BoolEval.FALSE;
+        }
+        return retval;
+    }
 }
index 7d47905a15da94811846aee0e4a4ecfa1d18cd80..53973d8db1f26a991586716a1e9a5f501e34fff3 100644 (file)
@@ -4,10 +4,73 @@
  */
 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.BlankEval;
+import org.apache.poi.hssf.record.formula.eval.BoolEval;
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.RefEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  *
  */
-public class Isblank extends DefaultFunctionImpl {
+public class Isblank implements Function {
 
+    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        boolean b = false;
+        
+        switch (operands.length) {
+        default:
+            retval = ErrorEval.VALUE_INVALID;
+            break;
+        case 1:
+            if (operands[0] instanceof BlankEval) {
+                b = true;
+            }
+            else if (operands[0] instanceof AreaEval) {
+                AreaEval ae = (AreaEval) operands[0];
+                if (ae.contains(srcCellRow, srcCellCol)) { // circular ref!
+                    retval = ErrorEval.CIRCULAR_REF_ERROR;
+                }
+                else if (ae.isRow()) {
+                    if (ae.containsColumn(srcCellCol)) {
+                        ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCellCol);
+                        b = (ve instanceof BlankEval);
+                    }
+                    else {
+                        b = false;
+                    }
+                }
+                else if (ae.isColumn()) {
+                    if (ae.containsRow(srcCellRow)) {
+                        ValueEval ve = ae.getValueAt(srcCellRow, ae.getFirstColumn());
+                        b = (ve instanceof BlankEval);
+                    }
+                    else {
+                        b = false;
+                    }
+                }
+                else {
+                    b = false;
+                }
+            }
+            else if (operands[0] instanceof RefEval) {
+                RefEval re = (RefEval) operands[0];
+                b = (!re.isEvaluated()) && re.getInnerValueEval() instanceof BlankEval; 
+            }
+            else {
+                b = false;
+            }
+        }
+        
+        if (retval == null) {
+            retval = b
+                    ? BoolEval.TRUE
+                    : BoolEval.FALSE;
+        }
+        return retval;
+    }
 }
index 79c9e3caa8397b4d8eb025103b90c3ff83453ff4..355bd718430ac6d7a57de16d57e8a3c76d6073a3 100644 (file)
@@ -4,10 +4,62 @@
  */
 package org.apache.poi.hssf.record.formula.functions;
 
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  *
  */
-public class Large extends DefaultFunctionImpl {
+public class Large extends MultiOperandNumericFunction {
+    private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
+        new ValueEvalToNumericXlator((short) (0
+                | ValueEvalToNumericXlator.BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
+                | ValueEvalToNumericXlator.STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE
+              //| ValueEvalToNumericXlator.EVALUATED_REF_BLANK_IS_PARSED
+              //| ValueEvalToNumericXlator.REF_BLANK_IS_PARSED
+              //| ValueEvalToNumericXlator.BLANK_IS_PARSED
+                ));
+    
+    /**
+     * this is the default impl for the factory method getXlator
+     * of the super class NumericFunction. Subclasses can override this method
+     * if they desire to return a different ValueEvalToNumericXlator instance
+     * than the default.
+     */
+    protected ValueEvalToNumericXlator getXlator() {
+        return DEFAULT_NUM_XLATOR;
+    }
 
+    
+    
+    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        double[] ops = getNumberArray(operands, srcCellRow, srcCellCol);
+        if (ops == null || ops.length < 2) {
+            retval = ErrorEval.VALUE_INVALID;
+        }
+        else {
+            double[] values = new double[ops.length-1];
+            int k = (int) ops[ops.length-1];
+            System.arraycopy(ops, 0, values, 0, values.length);
+            double d = StatsLib.kthLargest(values, k);
+            retval = (Double.isNaN(d) || Double.isInfinite(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
+        }
+        
+        return retval;
+    }
 }
index a9ac39874bab3911215e51fccf5ca56298b4cbca..c72146d8287bcdb00b49e469b1155bdb05dc316e 100644 (file)
  */
 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.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.RefEval;
+import org.apache.poi.hssf.record.formula.eval.StringValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  *
  */
-public class Len extends DefaultFunctionImpl {
+public class Len extends TextFunction {
+
+
+    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        String s = null;
+        
+        switch (operands.length) {
+        default:
+            retval = ErrorEval.VALUE_INVALID;
+            break;
+        case 1:
+            ValueEval ve = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol);
+            if (ve instanceof StringValueEval) {
+                StringValueEval sve = (StringValueEval) ve;
+                s = sve.getStringValue();
+            }
+            else if (ve instanceof RefEval) {
+                RefEval re = (RefEval) ve;
+                ValueEval ive = re.getInnerValueEval();
+                if (ive instanceof BlankEval) {
+                    s = re.isEvaluated() ? "0" : null;
+                }
+                else if (ive instanceof StringValueEval) {
+                    s = ((StringValueEval) ive).getStringValue();
+                }
+                else if (ive instanceof BlankEval) {}
+                else {
+                    retval = ErrorEval.VALUE_INVALID;
+                }
+            }
+            else if (ve instanceof BlankEval) {}
+            else {
+                retval = ErrorEval.VALUE_INVALID;
+                break;
+            }
+        }
+        
+        if (retval == null) {
+            s = (s == null) ? EMPTY_STRING : s;
+            retval = new NumberEval(s.length());
+        }
+        
+        return retval;
+    }
+    
+    
+    protected ValueEval singleOperandEvaluate(Eval eval, int srcRow, short srcCol) {
+        ValueEval retval;
+        if (eval instanceof AreaEval) {
+            AreaEval ae = (AreaEval) eval;
+            if (ae.contains(srcRow, srcCol)) { // circular ref!
+                retval = ErrorEval.CIRCULAR_REF_ERROR;
+            }
+            else if (ae.isRow()) {
+                if (ae.containsColumn(srcCol)) {
+                    ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol);
+                    retval = attemptXlateToText(ve);
+                }
+                else {
+                    retval = ErrorEval.VALUE_INVALID;
+                }
+            }
+            else if (ae.isColumn()) {
+                if (ae.containsRow(srcRow)) {
+                    ValueEval ve = ae.getValueAt(srcRow, ae.getFirstColumn());
+                    retval = attemptXlateToText(ve);
+                }
+                else {
+                    retval = ErrorEval.VALUE_INVALID;
+                }
+            }
+            else {
+                retval = ErrorEval.VALUE_INVALID;
+            }
+        }
+        else {
+            retval = attemptXlateToText((ValueEval) eval);
+        }
+        return retval;
+    }
 
+    
+    /**
+     * converts from Different ValueEval types to StringEval.
+     * Note: AreaEvals are not handled, if arg is an AreaEval,
+     * the returned value is ErrorEval.VALUE_INVALID
+     * @param ve
+     * @return
+     */
+    protected ValueEval attemptXlateToText(ValueEval ve) {
+        ValueEval retval;
+        if (ve instanceof StringValueEval || ve instanceof RefEval) {
+            retval = ve;
+        }
+        else if (ve instanceof BlankEval) {
+            retval = ve;
+        }
+        else {
+            retval = ErrorEval.VALUE_INVALID;
+        }
+        return retval;
+    }
 }
index 5e80259b9a430c08966a2ee4afc875dea6389469..fe3a6a2251ef0d0c3dd16a0eea43ae0ea54795fd 100644 (file)
@@ -14,29 +14,17 @@ import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
 
 /**
  * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- *  
+ *
  */
 public class Ln extends NumericFunction {
-    
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
 
     public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
         double d = 0;
         ValueEval retval = null;
-        
+
         switch (operands.length) {
         default:
+            retval = ErrorEval.VALUE_INVALID;
             break;
         case 1:
             ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
@@ -51,7 +39,7 @@ public class Ln extends NumericFunction {
                 retval = ErrorEval.NUM_ERROR;
             }
         }
-        
+
         if (retval == null) {
             d = Math.log(d);
             retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
index 044557b351e3b08cfec29007a9a3c516328c7eb0..3732f63db362efd60b8e57b2d6b7de3610f98f9a 100644 (file)
@@ -17,32 +17,20 @@ import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
  * Log: LOG(number,[base])
  */
 public class Log extends NumericFunction {
-    
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-    
-    private static final double DEFAULT_BASE = 10;
 
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
+    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 
+        case 2: // second arg is base
             ValueEval ve = singleOperandEvaluate(operands[1], srcRow, srcCol);
             if (ve instanceof NumericValueEval) {
                 NumericValueEval ne = (NumericValueEval) ve;
@@ -54,7 +42,7 @@ public class Log extends NumericFunction {
             else {
                 retval = ErrorEval.NUM_ERROR;
             }
-            
+
         case 1: // first arg is number
             if (retval == null) {
                 ValueEval vev = singleOperandEvaluate(operands[0], srcRow, srcCol);
@@ -70,9 +58,9 @@ public class Log extends NumericFunction {
                 }
             }
         }
-        
+
         if (retval == null) {
-            d = (base == E) 
+            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);
index ee8261cd54fc02e9b89d7e41806ad38a494e1210..d884eee432469acb956aa2f9319c72c5a2911e55 100644 (file)
@@ -10,35 +10,21 @@ 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;
- *  
+ *
  */
 public class Log10 extends NumericFunction {
     private static final double LOG_10_TO_BASE_e = Math.log(10);
 
-    
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
-
     public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
         double d = 0;
         ValueEval retval = null;
-        
+
         switch (operands.length) {
         default:
+            retval = ErrorEval.VALUE_INVALID;
             break;
         case 1:
             ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
@@ -53,10 +39,12 @@ public class Log10 extends NumericFunction {
                 retval = ErrorEval.NUM_ERROR;
             }
         }
-        
+
         if (retval == null) {
             d = Math.log(d) / LOG_10_TO_BASE_e;
-            retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
+            retval = (Double.isNaN(d) || Double.isInfinite(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
         }
         return retval;
     }
index e5b6f9dc6ca0872015073909dd3d612795cdb462..75aef4cdf333c80450a774fe02c829e55a0ae15d 100644 (file)
@@ -4,10 +4,46 @@
  */
 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.StringEval;
+import org.apache.poi.hssf.record.formula.eval.StringValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  *
  */
-public class Lower extends DefaultFunctionImpl {
+public class Lower extends TextFunction {
+
 
+    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        String s = null;
+        
+        switch (operands.length) {
+        default:
+            retval = ErrorEval.VALUE_INVALID;
+            break;
+        case 1:
+            ValueEval ve = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol);
+            if (ve instanceof StringValueEval) {
+                StringValueEval sve = (StringValueEval) ve;
+                s = sve.getStringValue();
+            }
+            else if (ve instanceof BlankEval) {}
+            else {
+                retval = ErrorEval.VALUE_INVALID;
+                break;
+            }
+        }
+        
+        if (retval == null) {
+            s = (s == null) ? EMPTY_STRING : s;
+            retval = new StringEval(s.toLowerCase());
+        }
+        
+        return retval;
+    }
 }
index 521bc15b4e36e24f345e9d9095bcc5c7521f1522..efe4b5cbb19288a4dc211cb349ed6b33b5b090ca 100644 (file)
@@ -4,10 +4,49 @@
  */
 package org.apache.poi.hssf.record.formula.functions;
 
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt; 
  *
  */
-public class Max extends DefaultFunctionImpl {
+public class Max extends MultiOperandNumericFunction {
+    private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
+        new ValueEvalToNumericXlator((short) (
+                  ValueEvalToNumericXlator.BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
+                | ValueEvalToNumericXlator.STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE  
+                ));
+    
+    protected ValueEvalToNumericXlator getXlator() {
+        return DEFAULT_NUM_XLATOR;
+    }
 
+    
+    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        double[] values = getNumberArray(operands, srcCellRow, srcCellCol);
+        if (values == null) {
+            retval = ErrorEval.VALUE_INVALID;
+        }
+        else {
+            double d = values.length > 0 ? MathX.max(values) : 0;
+            retval = (Double.isNaN(d) || Double.isInfinite(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
+        }
+        
+        return retval;
+    }
 }
index b9605ac3b61a186c92cc43b44b12b1dfd64bbe3b..2494c3bcc6a60bf442de1642629b21b12ad26b58 100644 (file)
@@ -4,10 +4,51 @@
  */
 package org.apache.poi.hssf.record.formula.functions;
 
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt; 
  *
  */
-public class Maxa extends DefaultFunctionImpl {
+public class Maxa extends MultiOperandNumericFunction {
+    private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
+        new ValueEvalToNumericXlator((short) (
+                  ValueEvalToNumericXlator.BOOL_IS_PARSED  
+                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
+                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
+                | ValueEvalToNumericXlator.STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
+                | ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE  
+                | ValueEvalToNumericXlator.BLANK_IS_PARSED
+                | ValueEvalToNumericXlator.REF_BLANK_IS_PARSED
+                ));
+    
+    protected ValueEvalToNumericXlator getXlator() {
+        return DEFAULT_NUM_XLATOR;
+    }
 
+    
+    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        double[] values = getNumberArray(operands, srcCellRow, srcCellCol);
+        if (values == null) {
+            retval = ErrorEval.VALUE_INVALID;
+        }
+        else {
+            double d = values.length > 0 ? MathX.max(values) : 0;
+            retval = (Double.isNaN(d) || Double.isInfinite(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
+        }
+        
+        return retval;
+    }
 }
index 917819ca0a17ad4ad5ac019d51f186c441ac86ec..9a7c175e999ce79125cfbb0a311b1f2744e924c6 100644 (file)
@@ -4,10 +4,58 @@
  */
 package org.apache.poi.hssf.record.formula.functions;
 
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  *
  */
-public class Median extends DefaultFunctionImpl {
+public class Median extends MultiOperandNumericFunction {
+    private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
+        new ValueEvalToNumericXlator((short) (0
+                | ValueEvalToNumericXlator.BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
+                | ValueEvalToNumericXlator.STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE
+              //| ValueEvalToNumericXlator.EVALUATED_REF_BLANK_IS_PARSED
+              //| ValueEvalToNumericXlator.REF_BLANK_IS_PARSED
+              //| ValueEvalToNumericXlator.BLANK_IS_PARSED
+                ));
+    
+    /**
+     * this is the default impl for the factory method getXlator
+     * of the super class NumericFunction. Subclasses can override this method
+     * if they desire to return a different ValueEvalToNumericXlator instance
+     * than the default.
+     */
+    protected ValueEvalToNumericXlator getXlator() {
+        return DEFAULT_NUM_XLATOR;
+    }
 
+    
+    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        double[] values = getNumberArray(operands, srcCellRow, srcCellCol);
+        if (values == null) {
+            retval = ErrorEval.VALUE_INVALID;
+        }
+        else {
+            double d = StatsLib.median(values);
+            retval = (Double.isNaN(d) || Double.isInfinite(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
+        }
+        
+        return retval;
+    }
 }
index ee3355f7be5d38739ba8d2b8dc5cbe01f1ac51d9..7fb00f14b37b8c226a936fc8950f2118a56bee1f 100644 (file)
@@ -4,10 +4,49 @@
  */
 package org.apache.poi.hssf.record.formula.functions;
 
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt; 
  *
  */
-public class Min extends DefaultFunctionImpl {
+public class Min extends MultiOperandNumericFunction {
+    private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
+        new ValueEvalToNumericXlator((short) (
+                  ValueEvalToNumericXlator.BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
+                | ValueEvalToNumericXlator.STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE  
+                ));
+    
+    protected ValueEvalToNumericXlator getXlator() {
+        return DEFAULT_NUM_XLATOR;
+    }
 
+    
+    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        double[] values = getNumberArray(operands, srcCellRow, srcCellCol);
+        if (values == null) {
+            retval = ErrorEval.VALUE_INVALID;
+        }
+        else {
+            double d = values.length > 0 ? MathX.min(values) : 0;
+            retval = (Double.isNaN(d) || Double.isInfinite(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
+        }
+        
+        return retval;
+    }
 }
index e75ab4d1477476fbf9c89ff4e9e4474e90f573c1..8be4320fe97d4077dd61e8a7ca70b998406143ff 100644 (file)
@@ -4,10 +4,51 @@
  */
 package org.apache.poi.hssf.record.formula.functions;
 
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt; 
  *
  */
-public class Mina extends DefaultFunctionImpl {
+public class Mina extends MultiOperandNumericFunction {
+    private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
+        new ValueEvalToNumericXlator((short) (
+                  ValueEvalToNumericXlator.BOOL_IS_PARSED  
+                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
+                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
+                | ValueEvalToNumericXlator.STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
+                | ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE
+                | ValueEvalToNumericXlator.REF_BLANK_IS_PARSED
+                | ValueEvalToNumericXlator.BLANK_IS_PARSED
+                ));
+    
+    protected ValueEvalToNumericXlator getXlator() {
+        return DEFAULT_NUM_XLATOR;
+    }
 
+    
+    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        double[] values = getNumberArray(operands, srcCellRow, srcCellCol);
+        if (values == null) {
+            retval = ErrorEval.VALUE_INVALID;
+        }
+        else {
+            double d = values.length > 0 ? MathX.min(values) : 0;
+            retval = (Double.isNaN(d) || Double.isInfinite(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
+        }
+        
+        return retval;
+    }
 }
index 696dabba49e363471cd0c1ebb04ba1e9a7645b43..d272c535d17714d1e356f7b790257b3d6e90809b 100644 (file)
@@ -4,10 +4,68 @@
  */
 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 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  *
  */
-public class Mod extends DefaultFunctionImpl {
+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;
+    }
 
 }
index c2e3b388bd8454dfb29e8366aab27beb2f3918f2..ae605881fd32f5087690696a11d5b96ab3754952 100644 (file)
@@ -4,10 +4,59 @@
  */
 package org.apache.poi.hssf.record.formula.functions;
 
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  *
  */
-public class Mode extends DefaultFunctionImpl {
+public class Mode extends MultiOperandNumericFunction {
+    private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
+        new ValueEvalToNumericXlator((short) (0
+              //| ValueEvalToNumericXlator.BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
+                | ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE
+              //| ValueEvalToNumericXlator.EVALUATED_REF_BLANK_IS_PARSED
+              //| ValueEvalToNumericXlator.REF_BLANK_IS_PARSED
+              //| ValueEvalToNumericXlator.BLANK_IS_PARSED
+                ));
+    
+    /**
+     * this is the default impl for the factory method getXlator
+     * of the super class NumericFunction. Subclasses can override this method
+     * if they desire to return a different ValueEvalToNumericXlator instance
+     * than the default.
+     */
+    protected ValueEvalToNumericXlator getXlator() {
+        return DEFAULT_NUM_XLATOR;
+    }
+
 
+    
+    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        double[] values = getNumberArray(operands, srcCellRow, srcCellCol);
+        if (values == null) {
+            retval = ErrorEval.VALUE_INVALID;
+        }
+        else {
+            double d = StatsLib.mode(values);
+            retval = (Double.isNaN(d) || Double.isInfinite(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
+        }
+        
+        return retval;
+    }
 }
index 24c4415b12c292e45f0a1f5ec4396afcb3a8ac7a..05b7346c19839c7e286c996c235e88fce734a31b 100644 (file)
@@ -18,8 +18,32 @@ public abstract class NumericFunction implements Function {
     
     protected static final double E = Math.E;
     protected static final double PI = Math.PI;
+    
+    private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
+        new ValueEvalToNumericXlator((short) (
+                  ValueEvalToNumericXlator.BOOL_IS_PARSED  
+                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
+                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
+                | ValueEvalToNumericXlator.STRING_IS_PARSED  
+                | ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
+                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE  
+                ));
+    
+    private static final int DEFAULT_MAX_NUM_OPERANDS = 30;
 
-    protected abstract ValueEvalToNumericXlator getXlator();
+    /**
+     * this is the default impl of the factory(ish) method getXlator.
+     * Subclasses can override this method
+     * if they desire to return a different ValueEvalToNumericXlator instance
+     * than the default.
+     */
+    protected ValueEvalToNumericXlator getXlator() {
+        return DEFAULT_NUM_XLATOR;
+    }
     
     protected ValueEval singleOperandEvaluate(Eval eval, int srcRow, short srcCol) {
         ValueEval retval;
index 3e35d4c2a9f906050a7ad43b7a736b4f862e9557..be1ecb5efde49aa834e3d7e0eb72d29cef237a82 100644 (file)
@@ -10,7 +10,6 @@ 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;
@@ -18,19 +17,6 @@ import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
  */
 public class Odd extends NumericFunction {
     
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
-
     public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
         double d = 0;
         ValueEval retval = null;
index 6721fc3e203962087c587a6db56e84e63067dd72..b29ec03282c6a1fda828498f12e695327f0e26f3 100644 (file)
@@ -10,27 +10,13 @@ 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;
  *  
  */
 public class Power extends NumericFunction {
-    
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
-
+   
     public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
         double d0 = 0;
         double d1 = 0;
index f6d64268bf0de7571272bcb01000ec61637c41e1..539304641b193db7ccc0617a6cb375ab1a60e863 100644 (file)
@@ -4,10 +4,49 @@
  */
 package org.apache.poi.hssf.record.formula.functions;
 
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  *
  */
-public class Product extends DefaultFunctionImpl {
+public class Product extends MultiOperandNumericFunction {
+    private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
+        new ValueEvalToNumericXlator((short) (
+                  ValueEvalToNumericXlator.BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
+                | ValueEvalToNumericXlator.STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE  
+                ));
+    
+    protected ValueEvalToNumericXlator getXlator() {
+        return DEFAULT_NUM_XLATOR;
+    }
 
+    
+    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        double[] values = getNumberArray(operands, srcCellRow, srcCellCol);
+        if (values == null) {
+            retval = ErrorEval.VALUE_INVALID;
+        }
+        else {
+            double d = MathX.product(values);
+            retval = (Double.isNaN(d) || Double.isInfinite(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
+        }
+        
+        return retval;
+    }
 }
index 3df708b4559619a30f6c37ebda054b755b83ed3d..f7c187ab60082ffde83b60d126dc8d15be3852f8 100644 (file)
@@ -10,7 +10,6 @@ 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;
@@ -18,19 +17,6 @@ import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
  */
 public class Radians extends NumericFunction {
     
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
-
     public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
         double d = 0;
         ValueEval retval = null;
index 93031f33d203aed340d99623d4debbe3556b63c1..965cb2a10a8aa7666b9b214319525e755fa41728 100644 (file)
@@ -4,10 +4,68 @@
  */
 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 
  *
  */
-public class Round extends DefaultFunctionImpl {
+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;
+    }
 }
index 0b789d172a9571b195bba06a83eb54ae9c947ce5..0daff4cc22b728470a0d0d21f17497a00b8294b2 100644 (file)
@@ -4,10 +4,68 @@
  */
 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 
  *
  */
-public class Rounddown extends DefaultFunctionImpl {
+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 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;
+    }
 }
index b374be7c9469a0ab3f201ab8d20f7a63b51ce0ad..e46ac44af772653bef48187eb017615de8650448 100644 (file)
@@ -4,10 +4,70 @@
  */
 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 
  *
  */
-public class Roundup extends DefaultFunctionImpl {
+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 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;
+    }
 }
index 1f0496f794b48ae0ca5da64b137a9d49333d374a..81bb4b1cd6051c53681352ed4e91bf72f475d497 100644 (file)
@@ -4,10 +4,50 @@
  */
 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.ValueEval;
+
 /**
  * @author 
  *
  */
-public class Row extends DefaultFunctionImpl {
+public class Row implements Function {
 
+    public Eval evaluate(Eval[] evals, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        int rnum = -1;
+        
+        switch (evals.length) {
+        default:
+            retval = ErrorEval.VALUE_INVALID;
+        case 1:
+            if (evals[0] instanceof AreaEval) {
+                AreaEval ae = (AreaEval) evals[0];
+                rnum = ae.getFirstRow();
+            }
+            else if (evals[0] instanceof RefEval) {
+                RefEval re = (RefEval) evals[0];
+                rnum = re.getRow();
+            }
+            else { // anything else is not valid argument
+                retval = ErrorEval.VALUE_INVALID;
+            }
+            break;
+        case 0:
+            rnum = srcCellRow;
+        }
+        
+        if (retval == null) {
+            retval = (rnum >= 0)
+                    ? new NumberEval(rnum + 1) // +1 since excel rownums are 1 based
+                    : (ValueEval) ErrorEval.VALUE_INVALID;
+        }
+        
+        return retval;
+    }
+    
 }
index 3894bee5a43ae84064b142effeafd1123d596016..8f7c45e609c6406ca6304b53c529d1714c124d16 100644 (file)
@@ -10,7 +10,6 @@ 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 
@@ -18,19 +17,6 @@ import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
  */
 public class Sign extends NumericFunction {
     
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
-
     public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
         double d = 0;
         ValueEval retval = null;
@@ -56,11 +42,7 @@ public class Sign extends NumericFunction {
         if (retval == null) {
             retval = (Double.isNaN(d) || Double.isInfinite(d)) 
                     ? (ValueEval) ErrorEval.VALUE_INVALID 
-                    : (d == 0) 
-                        ? new NumberEval(0)
-                        : (d < 0)
-                            ? new NumberEval(-1)
-                            : new NumberEval(1);
+                    : new NumberEval(MathX.sign(d));
         }
         return retval;
     }
index 8d36bcb0dd2ab0cdd02740250c776ebe77b8fe20..ab7dbda6a07af931b8fab8ad01a7b5f93c3cf5a8 100644 (file)
@@ -10,33 +10,20 @@ 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;
- *  
+ *
  */
 public class Sin extends NumericFunction {
-    
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
 
     public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
         double d = 0;
         ValueEval retval = null;
-        
+
         switch (operands.length) {
         default:
+            retval = ErrorEval.VALUE_INVALID;
             break;
         case 1:
             ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
@@ -51,10 +38,12 @@ public class Sin extends NumericFunction {
                 retval = ErrorEval.NUM_ERROR;
             }
         }
-        
+
         if (retval == null) {
             d = Math.sin(d);
-            retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
+            retval = (Double.isNaN(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
         }
         return retval;
     }
index 5624bf2f590d95e8c4d401a977bcfc835153323b..b9bc61ecae616d964bc2b3f098cf65571939a97a 100644 (file)
@@ -10,33 +10,20 @@ 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;
- *  
+ *
  */
 public class Sinh extends NumericFunction {
-    
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
 
     public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
         double d = 0;
         ValueEval retval = null;
-        
+
         switch (operands.length) {
         default:
+            retval = ErrorEval.VALUE_INVALID;
             break;
         case 1:
             ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
@@ -51,12 +38,12 @@ public class Sinh extends NumericFunction {
                 retval = ErrorEval.NUM_ERROR;
             }
         }
-        
+
         if (retval == null) {
-            double ePowX = Math.pow(E, d);
-            double ePowNegX = Math.pow(E, -d);
-            d = (ePowX - ePowNegX) / 2;
-            retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
+            d = MathX.sinh(d);
+            retval = (Double.isNaN(d) || Double.isInfinite(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
         }
         return retval;
     }
index 667ab1188238e21cdafd6f0884a6fdcb6eeab543..338750c02f157702d516634792e15226dbda64f6 100644 (file)
@@ -4,10 +4,62 @@
  */
 package org.apache.poi.hssf.record.formula.functions;
 
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  *
  */
-public class Small extends DefaultFunctionImpl {
+public class Small extends MultiOperandNumericFunction {
+    private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
+        new ValueEvalToNumericXlator((short) (0
+                | ValueEvalToNumericXlator.BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
+                | ValueEvalToNumericXlator.STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE
+              //| ValueEvalToNumericXlator.EVALUATED_REF_BLANK_IS_PARSED
+              //| ValueEvalToNumericXlator.REF_BLANK_IS_PARSED
+              //| ValueEvalToNumericXlator.BLANK_IS_PARSED
+                ));
+    
+    /**
+     * this is the default impl for the factory method getXlator
+     * of the super class NumericFunction. Subclasses can override this method
+     * if they desire to return a different ValueEvalToNumericXlator instance
+     * than the default.
+     */
+    protected ValueEvalToNumericXlator getXlator() {
+        return DEFAULT_NUM_XLATOR;
+    }
 
+    
+    
+    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        double[] ops = getNumberArray(operands, srcCellRow, srcCellCol);
+        if (ops == null || ops.length < 2) {
+            retval = ErrorEval.VALUE_INVALID;
+        }
+        else {
+            double[] values = new double[ops.length-1];
+            int k = (int) ops[ops.length-1];
+            System.arraycopy(ops, 0, values, 0, values.length);
+            double d = StatsLib.kthSmallest(values, k);
+            retval = (Double.isNaN(d) || Double.isInfinite(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
+        }
+        
+        return retval;
+    }
 }
index fd6b76bf514780f8001e2e4cd1790e666584fe67..d990e55744b440b56c660a9c44f28d1b5e4775d9 100644 (file)
@@ -10,33 +10,20 @@ 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;
- *  
+ *
  */
 public class Sqrt extends NumericFunction {
-    
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
 
     public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
         double d = 0;
         ValueEval retval = null;
-        
+
         switch (operands.length) {
         default:
+            retval = ErrorEval.VALUE_INVALID;
             break;
         case 1:
             ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
@@ -51,10 +38,12 @@ public class Sqrt extends NumericFunction {
                 retval = ErrorEval.NUM_ERROR;
             }
         }
-        
+
         if (retval == null) {
             d = Math.sqrt(d);
-            retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
+            retval = (Double.isNaN(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
         }
         return retval;
     }
index 27559bc90f5cdf1f363fba69624ad08658f269b7..fdb4b75f47ac75a44cdd41d94c659d6f319857eb 100644 (file)
@@ -4,10 +4,58 @@
  */
 package org.apache.poi.hssf.record.formula.functions;
 
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  *
  */
-public class Stdev extends DefaultFunctionImpl {
+public class Stdev extends MultiOperandNumericFunction {
+
+    private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
+        new ValueEvalToNumericXlator((short) (0
+              //    ValueEvalToNumericXlator.BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
+                | ValueEvalToNumericXlator.STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE
+                | ValueEvalToNumericXlator.EVALUATED_REF_BLANK_IS_PARSED
+                ));
+    
+    /**
+     * this is the default impl for the factory method getXlator
+     * of the super class NumericFunction. Subclasses can override this method
+     * if they desire to return a different ValueEvalToNumericXlator instance
+     * than the default.
+     */
+    protected ValueEvalToNumericXlator getXlator() {
+        return DEFAULT_NUM_XLATOR;
+    }
 
+    
+    
+    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        double[] values = getNumberArray(operands, srcCellRow, srcCellCol);
+        if (values == null) {
+            retval = ErrorEval.VALUE_INVALID;
+        }
+        else {
+            double d = StatsLib.stdev(values);
+            retval = (Double.isNaN(d) || Double.isInfinite(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
+        }
+        
+        return retval;
+    }
 }
index 7b096531958788fd41bb7918142690fb79e7483d..e4003087d621360079bdf5cc7549e052cf4c74e6 100644 (file)
@@ -4,10 +4,49 @@
  */
 package org.apache.poi.hssf.record.formula.functions;
 
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt; 
  *
  */
-public class Sum extends DefaultFunctionImpl {
+public class Sum extends MultiOperandNumericFunction {
+    private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
+        new ValueEvalToNumericXlator((short) (
+                  ValueEvalToNumericXlator.BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
+                | ValueEvalToNumericXlator.STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE  
+                ));
+    
+    protected ValueEvalToNumericXlator getXlator() {
+        return DEFAULT_NUM_XLATOR;
+    }
 
+    
+    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        double[] values = getNumberArray(operands, srcCellRow, srcCellCol);
+        if (values == null) {
+            retval = ErrorEval.VALUE_INVALID;
+        }
+        else {
+            double d = values.length > 0 ? MathX.sum(values) : 0;
+            retval = (Double.isNaN(d) || Double.isInfinite(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
+        }
+        
+        return retval;
+    }
 }
index 8ef361de31faa8d43922f292003ecddd8c6f9034..e794b17482cdf249c05717a9b637c325be98e4ae 100644 (file)
@@ -4,10 +4,10 @@
  */
 package org.apache.poi.hssf.record.formula.functions;
 
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt; 
  *
  */
 public class Sumproduct extends DefaultFunctionImpl {
-
 }
index 2f13693bc4df2c0d766efe93294176763effb5db..bf0dd80a498321784a6535161fde6bb937c1e0c4 100644 (file)
@@ -4,10 +4,51 @@
  */
 package org.apache.poi.hssf.record.formula.functions;
 
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt; 
  *
  */
-public class Sumsq extends DefaultFunctionImpl {
+public class Sumsq extends MultiOperandNumericFunction {
+    private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
+        new ValueEvalToNumericXlator((short) (
+              //  ValueEvalToNumericXlator.BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED  
+              //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE  
+              //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE  
+                  ValueEvalToNumericXlator.REF_BLANK_IS_PARSED
+                | ValueEvalToNumericXlator.BLANK_IS_PARSED
+                ));
+    
+    protected ValueEvalToNumericXlator getXlator() {
+        return DEFAULT_NUM_XLATOR;
+    }
 
+    
+    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        double[] values = getNumberArray(operands, srcCellRow, srcCellCol);
+        if (values == null) {
+            retval = ErrorEval.VALUE_INVALID;
+        }
+        else {
+            double d = MathX.sumsq(values);
+            retval = (Double.isNaN(d) || Double.isInfinite(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
+        }
+        
+        return retval;
+    }
 }
index 4a0267e88976162c6ac4a3fb2ebb2da069cbe0c9..98e9447f8d8cc663e6f8df13cdaab1bc5bae52ce 100644 (file)
@@ -4,10 +4,44 @@
  */
 package org.apache.poi.hssf.record.formula.functions;
 
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt; 
  *
  */
-public class Sumx2my2 extends DefaultFunctionImpl {
+public class Sumx2my2 extends XYNumericFunction {
 
+    
+    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        double[][] values = null;
+        
+        int checkLen = 0; // check to see that all array lengths are equal
+        switch (operands.length) {
+        default:
+            retval = ErrorEval.VALUE_INVALID;
+            break;
+        case 2:
+            values = getValues(operands, srcCellRow, srcCellCol);
+            if (values==null 
+                    || values[X] == null || values[Y] == null
+                    || values[X].length == 0 || values[Y].length == 0
+                    || values[X].length != values[Y].length) {
+                retval = ErrorEval.VALUE_INVALID;
+            }
+        }
+        
+        if (retval == null) {
+            double d = MathX.sumx2my2(values[X], values[Y]);
+            retval = (Double.isNaN(d) || Double.isInfinite(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
+        }
+        
+        return retval;
+    }
 }
index 5535612c775aeeb02d9497a76f8a27ea1493dfd3..da8771038b7acbb5240ff7bcb35db6cc3eb78ed3 100644 (file)
@@ -4,10 +4,44 @@
  */
 package org.apache.poi.hssf.record.formula.functions;
 
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt; 
  *
  */
-public class Sumx2py2 extends DefaultFunctionImpl {
+public class Sumx2py2 extends XYNumericFunction {
 
+    
+    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        double[][] values = null;
+        
+        int checkLen = 0; // check to see that all array lengths are equal
+        switch (operands.length) {
+        default:
+            retval = ErrorEval.VALUE_INVALID;
+            break;
+        case 2:
+            values = getValues(operands, srcCellRow, srcCellCol);
+            if (values==null 
+                    || values[X] == null || values[Y] == null
+                    || values[X].length == 0 || values[Y].length == 0
+                    || values[X].length != values[Y].length) {
+                retval = ErrorEval.VALUE_INVALID;
+            }
+        }
+        
+        if (retval == null) {
+            double d = MathX.sumx2py2(values[X], values[Y]);
+            retval = (Double.isNaN(d) || Double.isInfinite(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
+        }
+        
+        return retval;
+    }
 }
index 60aed2ebb57e4d646091bc0def3ed6405701cf0c..1998481ebffdaf252f4b0a0349cba0e7e31f6adb 100644 (file)
@@ -4,10 +4,44 @@
  */
 package org.apache.poi.hssf.record.formula.functions;
 
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt; 
  *
  */
-public class Sumxmy2 extends DefaultFunctionImpl {
+public class Sumxmy2 extends XYNumericFunction {
 
+    
+    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        double[][] values = null;
+        
+        int checkLen = 0; // check to see that all array lengths are equal
+        switch (operands.length) {
+        default:
+            retval = ErrorEval.VALUE_INVALID;
+            break;
+        case 2:
+            values = getValues(operands, srcCellRow, srcCellCol);
+            if (values==null 
+                    || values[X] == null || values[Y] == null
+                    || values[X].length == 0 || values[Y].length == 0
+                    || values[X].length != values[Y].length) {
+                retval = ErrorEval.VALUE_INVALID;
+            }
+        }
+        
+        if (retval == null) {
+            double d = MathX.sumxmy2(values[X], values[Y]);
+            retval = (Double.isNaN(d) || Double.isInfinite(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
+        }
+        
+        return retval;
+    }
 }
index 117e8a1d359b857302c9df7868393c66f407db89..2aa675caad7efc8c0025690ad71c9e64dae831ed 100644 (file)
@@ -4,10 +4,34 @@
  */
 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.StringEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
 /**
  * @author 
  *
  */
-public class T extends DefaultFunctionImpl {
+public class T implements Function {
+    
+    
 
+    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        switch (operands.length) {
+        default:
+            retval = ErrorEval.VALUE_INVALID;
+            break;
+        case 1:
+            if (operands[0] instanceof StringEval
+             || operands[0] instanceof ErrorEval) {
+                retval = (ValueEval) operands[0];
+            }
+            else if (operands[0] instanceof ErrorEval) {
+                retval = StringEval.EMPTY_INSTANCE;
+            }
+        }
+        return retval;
+    }
 }
index 972148acc9a059ad25088f24ad9c3200184eb2aa..4391b219ce24c363d01a08d7e7d5f72652f9d72d 100644 (file)
@@ -10,33 +10,20 @@ 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;
- *  
+ *
  */
 public class Tan extends NumericFunction {
-    
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
 
     public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
         double d = 0;
         ValueEval retval = null;
-        
+
         switch (operands.length) {
         default:
+            retval = ErrorEval.VALUE_INVALID;
             break;
         case 1:
             ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
@@ -51,10 +38,12 @@ public class Tan extends NumericFunction {
                 retval = ErrorEval.NUM_ERROR;
             }
         }
-        
+
         if (retval == null) {
             d = Math.tan(d);
-            retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
+            retval = (Double.isNaN(d))
+                    ? (ValueEval) ErrorEval.VALUE_INVALID
+                    : new NumberEval(d);
         }
         return retval;
     }
index 1c6a1ec262cb69af37a0cd2bf8f3122f32fb18ff..742ad3018ba42eb8061ca240fa86d333266d68ad 100644 (file)
@@ -10,33 +10,20 @@ 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;
- *  
+ *
  */
 public class Tanh extends NumericFunction {
-    
-    private static final ValueEvalToNumericXlator NUM_XLATOR = 
-        new ValueEvalToNumericXlator((short)
-                ( ValueEvalToNumericXlator.BOOL_IS_PARSED 
-                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED
-                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED
-                | ValueEvalToNumericXlator.STRING_IS_PARSED
-                ));
-
-    protected ValueEvalToNumericXlator getXlator() {
-        return NUM_XLATOR;
-    }
 
     public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
         double d = 0;
         ValueEval retval = null;
-        
+
         switch (operands.length) {
         default:
+            retval = ErrorEval.VALUE_INVALID;
             break;
         case 1:
             ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
@@ -51,12 +38,12 @@ public class Tanh extends NumericFunction {
                 retval = ErrorEval.NUM_ERROR;
             }
         }
-        
+
         if (retval == null) {
-            double ePowX = Math.pow(E, d);
-            double ePowNegX = Math.pow(E, -d);
-            d = (ePowX - ePowNegX) / (ePowX + ePowNegX);
-            retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
+            d = MathX.tanh(d);
+            retval = (Double.isNaN(d) || Double.isInfinite(d))
+                    ? (ValueEval) ErrorEval.NUM_ERROR
+                    : new NumberEval(d);
         }
         return retval;
     }
index 46d137249c284b2d80575aa548e46a04d2aba3bb..4618a2b1e3035cff585a336a8a423bc4b431d1b4 100644 (file)
@@ -4,10 +4,46 @@
  */
 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.StringEval;
+import org.apache.poi.hssf.record.formula.eval.StringValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
 /**
- * @author 
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  *
  */
-public class Upper extends DefaultFunctionImpl {
+public class Upper extends TextFunction {
+
 
+    public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+        ValueEval retval = null;
+        String s = null;
+        
+        switch (operands.length) {
+        default:
+            retval = ErrorEval.VALUE_INVALID;
+            break;
+        case 1:
+            ValueEval ve = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol);
+            if (ve instanceof StringValueEval) {
+                StringValueEval sve = (StringValueEval) ve;
+                s = sve.getStringValue();
+            }
+            else if (ve instanceof BlankEval) {}
+            else {
+                retval = ErrorEval.VALUE_INVALID;
+                break;
+            }
+        }
+        
+        if (retval == null) {
+            s = (s == null) ? EMPTY_STRING : s;
+            retval = new StringEval(s.toUpperCase());
+        }
+        
+        return retval;
+    }
 }
index 6d6aa1bf56717dbd81cb3bf4e49a206c245eddca..850fbd1a1ba16888ab671c995b3df1e096c152a6 100644 (file)
@@ -280,7 +280,6 @@ public class HSSFFormulaEvaluator {
     protected static ValueEval internalEvaluate(HSSFCell srcCell, HSSFRow srcRow, HSSFSheet sheet, HSSFWorkbook workbook) {
         int srcRowNum = srcRow.getRowNum();
         short srcColNum = srcCell.getCellNum();
-        
         FormulaParser parser = new FormulaParser(srcCell.getCellFormula(), workbook.getWorkbook());
         parser.parse();
         Ptg[] ptgs = parser.getRPNPtg();
@@ -314,9 +313,6 @@ public class HSSFFormulaEvaluator {
                 // storing the ops in reverse order since they are popping
                 for (int j = numops - 1; j >= 0; j--) {
                     Eval p = (Eval) stack.pop();
-                    if (p instanceof ErrorEval) { // fast fail
-                        return (ErrorEval) p;
-                    }
                     ops[j] = p;
                 }
                 Eval opresult = operation.evaluate(ops, srcRowNum, srcColNum);
@@ -482,7 +478,7 @@ public class HSSFFormulaEvaluator {
                 retval = new StringEval(cell.getStringCellValue());
                 break;
             case HSSFCell.CELL_TYPE_FORMULA:
-                retval = (ValueEval) internalEvaluate(cell, row, sheet, workbook);
+                retval = internalEvaluate(cell, row, sheet, workbook);
                 break;
             case HSSFCell.CELL_TYPE_BOOLEAN:
                 retval = cell.getBooleanCellValue() ? BoolEval.TRUE : BoolEval.FALSE;
index e7921e3d11049f43db96fc68ad976b539ed62d33..5920863cf6a49c52ea93d0e3797deb2554476aa0 100644 (file)
Binary files a/src/scratchpad/testcases/org/apache/poi/hssf/data/FormulaEvalTestData.xls and b/src/scratchpad/testcases/org/apache/poi/hssf/data/FormulaEvalTestData.xls differ
index 57e13758179c39a283f35fc5618ebff875247740..ded15ffeba8a07277fcb09ecf58819234a14c53a 100644 (file)
@@ -4,12 +4,12 @@
  */
 package org.apache.poi.hssf.record.formula.eval;
 
-import java.io.File;
 import java.io.FileInputStream;
 
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 
+import org.apache.poi.hssf.record.formula.functions.TestMathX;
 import org.apache.poi.hssf.usermodel.HSSFCell;
 import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
 import org.apache.poi.hssf.usermodel.HSSFRow;
@@ -77,12 +77,13 @@ public class GenericFormulaTestCase extends TestCase {
                     assertEquals(msg, HSSFCell.CELL_TYPE_ERROR, actual.getCellType()); // TODO: check if exact error matches
                     break;
                 case HSSFCell.CELL_TYPE_FORMULA: // will never be used, since we will call method after formula evaluation
-                    throw new AssertionFailedError("Cannot expect formula as result of formula evaluation");
+                    throw new AssertionFailedError("Cannot expect formula as result of formula evaluation: " + msg);
                 case HSSFCell.CELL_TYPE_NUMERIC:
                     assertEquals(msg, HSSFCell.CELL_TYPE_NUMERIC, actual.getCellType());
-                    double delta = Math.abs(expected.getNumericCellValue()-actual.getNumberValue());
-                    double pctExpected = Math.abs(0.00001*expected.getNumericCellValue());
-                    assertTrue(msg, delta <= pctExpected);
+                    TestMathX.assertEquals(msg, expected.getNumericCellValue(), actual.getNumberValue(), TestMathX.POS_ZERO, TestMathX.DIFF_TOLERANCE_FACTOR);
+//                    double delta = Math.abs(expected.getNumericCellValue()-actual.getNumberValue());
+//                    double pctExpected = Math.abs(0.00001*expected.getNumericCellValue());
+//                    assertTrue(msg, delta <= pctExpected);
                     break;
                 case HSSFCell.CELL_TYPE_STRING:
                     assertEquals(msg, HSSFCell.CELL_TYPE_STRING, actual.getCellType());
@@ -113,18 +114,20 @@ public class GenericFormulaTestCase extends TestCase {
 
         HSSFCell c = null;
         for (short colnum=getBeginCol(); colnum < endcolnum; colnum++) {
+            try {
             c = r.getCell(colnum);
-            if (c==null || c.getCellType() == HSSFCell.CELL_TYPE_BLANK)
+            if (c==null || c.getCellType() != HSSFCell.CELL_TYPE_FORMULA)
                 continue;
             
-            assertEquals("Sanity check input cell type ", HSSFCell.CELL_TYPE_FORMULA, c.getCellType());
-            
             HSSFFormulaEvaluator.CellValue actualValue = evaluator.evaluate(c);
             
             HSSFCell expectedValueCell = getExpectedValueCell(s, r, c);
             assertEquals("Formula: " + c.getCellFormula() 
                     + " @ " + getBeginRow() + ":" + colnum, 
                     expectedValueCell, actualValue);
+            } catch (RuntimeException re) {
+                throw new RuntimeException("CELL["+getBeginRow()+","+colnum+"]: "+re.getMessage(), re);
+            }
         }
     }
     
index 6c30b30fb777b45f79306dd3800a982d58e6da00..85f51af6002aa19694afeecce929281eaf9c9ec1 100644 (file)
@@ -21,6 +21,7 @@ public class TestEverything extends TestSuite {
                s = "D"+Integer.toString(i).trim();
                suite.addTest(new GenericFormulaTestCase(s));
         }
+//        suite.addTest(new GenericFormulaTestCase("D1164"));
         return suite;
     }
 }