mirror of https://github.com/apache/poi.git
replace over engineered inner classes with lambdas/method references
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1888743 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
3c03974499
commit
240b02daec
|
@ -73,9 +73,9 @@ public final class FunctionEval {
|
||||||
retval[5] = AggregateFunction.AVERAGE;
|
retval[5] = AggregateFunction.AVERAGE;
|
||||||
retval[6] = AggregateFunction.MIN;
|
retval[6] = AggregateFunction.MIN;
|
||||||
retval[7] = AggregateFunction.MAX;
|
retval[7] = AggregateFunction.MAX;
|
||||||
retval[8] = new RowFunc(); // ROW
|
retval[8] = RowFunc::evaluate; // ROW
|
||||||
retval[9] = new Column();
|
retval[9] = Column::evaluate;
|
||||||
retval[10] = new Na();
|
retval[10] = Na::evaluate;
|
||||||
retval[11] = new Npv();
|
retval[11] = new Npv();
|
||||||
retval[12] = AggregateFunction.STDEV;
|
retval[12] = AggregateFunction.STDEV;
|
||||||
retval[13] = NumericFunction.DOLLAR;
|
retval[13] = NumericFunction.DOLLAR;
|
||||||
|
@ -137,7 +137,7 @@ public final class FunctionEval {
|
||||||
retval[71] = CalendarFieldFunction.HOUR;
|
retval[71] = CalendarFieldFunction.HOUR;
|
||||||
retval[72] = CalendarFieldFunction.MINUTE;
|
retval[72] = CalendarFieldFunction.MINUTE;
|
||||||
retval[73] = CalendarFieldFunction.SECOND;
|
retval[73] = CalendarFieldFunction.SECOND;
|
||||||
retval[74] = new Now();
|
retval[74] = Now::evaluate;
|
||||||
retval[75] = new Areas();
|
retval[75] = new Areas();
|
||||||
retval[76] = new Rows();
|
retval[76] = new Rows();
|
||||||
retval[77] = new Columns();
|
retval[77] = new Columns();
|
||||||
|
@ -226,7 +226,7 @@ public final class FunctionEval {
|
||||||
retval[216] = new Rank();
|
retval[216] = new Rank();
|
||||||
retval[219] = new Address();
|
retval[219] = new Address();
|
||||||
retval[220] = new Days360();
|
retval[220] = new Days360();
|
||||||
retval[221] = new Today();
|
retval[221] = Today::evaluate;
|
||||||
//222: VBD
|
//222: VBD
|
||||||
|
|
||||||
retval[227] = AggregateFunction.MEDIAN;
|
retval[227] = AggregateFunction.MEDIAN;
|
||||||
|
@ -259,7 +259,7 @@ public final class FunctionEval {
|
||||||
retval[276] = NumericFunction.COMBIN;
|
retval[276] = NumericFunction.COMBIN;
|
||||||
// 277: CONFIDENCE
|
// 277: CONFIDENCE
|
||||||
// 278:CRITBINOM
|
// 278:CRITBINOM
|
||||||
retval[279] = new Even();
|
retval[279] = NumericFunction.EVEN;
|
||||||
// 280: EXPONDIST
|
// 280: EXPONDIST
|
||||||
// 281: FDIST
|
// 281: FDIST
|
||||||
// 282: FINV
|
// 282: FINV
|
||||||
|
@ -278,7 +278,7 @@ public final class FunctionEval {
|
||||||
// 295: NORMINV
|
// 295: NORMINV
|
||||||
// 296: NORMSINV
|
// 296: NORMSINV
|
||||||
// 297: STANDARDIZE
|
// 297: STANDARDIZE
|
||||||
retval[298] = new Odd();
|
retval[298] = NumericFunction.ODD;
|
||||||
// 299: PERMUT
|
// 299: PERMUT
|
||||||
retval[300] = NumericFunction.POISSON;
|
retval[300] = NumericFunction.POISSON;
|
||||||
// 301: TDIST
|
// 301: TDIST
|
||||||
|
|
|
@ -32,10 +32,10 @@ public interface ArrayFunction {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param args the evaluated function arguments. Empty values are represented with
|
* @param args the evaluated function arguments. Empty values are represented with
|
||||||
* {@link BlankEval} or {@link MissingArgEval}, never <code>null</code>.
|
* {@link BlankEval} or {@link MissingArgEval}, never {@code null}.
|
||||||
* @param srcRowIndex row index of the cell containing the formula under evaluation
|
* @param srcRowIndex row index of the cell containing the formula under evaluation
|
||||||
* @param srcColumnIndex column index of the cell containing the formula under evaluation
|
* @param srcColumnIndex column index of the cell containing the formula under evaluation
|
||||||
* @return The evaluated result, possibly an {@link ErrorEval}, never <code>null</code>.
|
* @return The evaluated result, possibly an {@link ErrorEval}, never {@code null}.
|
||||||
* <b>Note</b> - Excel uses the error code <i>#NUM!</i> instead of IEEE <i>NaN</i>, so when
|
* <b>Note</b> - Excel uses the error code <i>#NUM!</i> instead of IEEE <i>NaN</i>, so when
|
||||||
* numeric functions evaluate to {@link Double#NaN} be sure to translate the result to {@link
|
* numeric functions evaluate to {@link Double#NaN} be sure to translate the result to {@link
|
||||||
* ErrorEval#NUM_ERROR}.
|
* ErrorEval#NUM_ERROR}.
|
||||||
|
@ -47,19 +47,29 @@ public interface ArrayFunction {
|
||||||
* Evaluate an array function with two arguments.
|
* Evaluate an array function with two arguments.
|
||||||
*
|
*
|
||||||
* @param arg0 the first function argument. Empty values are represented with
|
* @param arg0 the first function argument. Empty values are represented with
|
||||||
* {@link BlankEval} or {@link MissingArgEval}, never <code>null</code>
|
* {@link BlankEval} or {@link MissingArgEval}, never {@code null}
|
||||||
* @param arg1 the first function argument. Empty values are represented with
|
* @param arg1 the first function argument. Empty values are represented with
|
||||||
* @link BlankEval} or {@link MissingArgEval}, never <code>null</code>
|
* @link BlankEval} or {@link MissingArgEval}, never {@code null}
|
||||||
*
|
*
|
||||||
* @param srcRowIndex row index of the cell containing the formula under evaluation
|
* @param srcRowIndex row index of the cell containing the formula under evaluation
|
||||||
* @param srcColumnIndex column index of the cell containing the formula under evaluation
|
* @param srcColumnIndex column index of the cell containing the formula under evaluation
|
||||||
* @return The evaluated result, possibly an {@link ErrorEval}, never <code>null</code>.
|
* @return The evaluated result, possibly an {@link ErrorEval}, never {@code null}.
|
||||||
* <b>Note</b> - Excel uses the error code <i>#NUM!</i> instead of IEEE <i>NaN</i>, so when
|
* <b>Note</b> - Excel uses the error code <i>#NUM!</i> instead of IEEE <i>NaN</i>, so when
|
||||||
* numeric functions evaluate to {@link Double#NaN} be sure to translate the result to {@link
|
* numeric functions evaluate to {@link Double#NaN} be sure to translate the result to {@link
|
||||||
* ErrorEval#NUM_ERROR}.
|
* ErrorEval#NUM_ERROR}.
|
||||||
*/
|
*/
|
||||||
default ValueEval evaluateTwoArrayArgs(ValueEval arg0, ValueEval arg1, int srcRowIndex, int srcColumnIndex,
|
default ValueEval evaluateTwoArrayArgs(ValueEval arg0, ValueEval arg1, int srcRowIndex, int srcColumnIndex,
|
||||||
BiFunction<ValueEval, ValueEval, ValueEval> evalFunc) {
|
BiFunction<ValueEval, ValueEval, ValueEval> evalFunc) {
|
||||||
|
return _evaluateTwoArrayArgs(arg0, arg1, srcRowIndex, srcColumnIndex, evalFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
default ValueEval evaluateOneArrayArg(ValueEval arg0, int srcRowIndex, int srcColumnIndex,
|
||||||
|
java.util.function.Function<ValueEval, ValueEval> evalFunc) {
|
||||||
|
return _evaluateOneArrayArg(arg0, srcRowIndex, srcColumnIndex, evalFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ValueEval _evaluateTwoArrayArgs(ValueEval arg0, ValueEval arg1, int srcRowIndex, int srcColumnIndex,
|
||||||
|
BiFunction<ValueEval, ValueEval, ValueEval> evalFunc) {
|
||||||
int w1, w2, h1, h2;
|
int w1, w2, h1, h2;
|
||||||
int a1FirstCol = 0, a1FirstRow = 0;
|
int a1FirstCol = 0, a1FirstRow = 0;
|
||||||
if (arg0 instanceof AreaEval) {
|
if (arg0 instanceof AreaEval) {
|
||||||
|
@ -150,8 +160,9 @@ public interface ArrayFunction {
|
||||||
return new CacheAreaEval(srcRowIndex, srcColumnIndex, srcRowIndex + height - 1, srcColumnIndex + width - 1, vals);
|
return new CacheAreaEval(srcRowIndex, srcColumnIndex, srcRowIndex + height - 1, srcColumnIndex + width - 1, vals);
|
||||||
}
|
}
|
||||||
|
|
||||||
default ValueEval evaluateOneArrayArg(ValueEval arg0, int srcRowIndex, int srcColumnIndex,
|
|
||||||
java.util.function.Function<ValueEval, ValueEval> evalFunc){
|
static ValueEval _evaluateOneArrayArg(ValueEval arg0, int srcRowIndex, int srcColumnIndex,
|
||||||
|
java.util.function.Function<ValueEval, ValueEval> evalFunc){
|
||||||
int w1, w2, h1, h2;
|
int w1, w2, h1, h2;
|
||||||
int a1FirstCol = 0, a1FirstRow = 0;
|
int a1FirstCol = 0, a1FirstRow = 0;
|
||||||
if (arg0 instanceof AreaEval) {
|
if (arg0 instanceof AreaEval) {
|
||||||
|
@ -204,7 +215,6 @@ public interface ArrayFunction {
|
||||||
}
|
}
|
||||||
|
|
||||||
return new CacheAreaEval(srcRowIndex, srcColumnIndex, srcRowIndex + height - 1, srcColumnIndex + width - 1, vals);
|
return new CacheAreaEval(srcRowIndex, srcColumnIndex, srcRowIndex + height - 1, srcColumnIndex + width - 1, vals);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,6 @@ import org.apache.poi.ss.formula.eval.ValueEval;
|
||||||
* <li> Numbers: 0 is false. Any other number is TRUE </li>
|
* <li> Numbers: 0 is false. Any other number is TRUE </li>
|
||||||
* <li> Areas: *all* cells in area are evaluated according to the above rules</li>
|
* <li> Areas: *all* cells in area are evaluated according to the above rules</li>
|
||||||
* </ol>
|
* </ol>
|
||||||
*
|
|
||||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
|
||||||
*/
|
*/
|
||||||
public abstract class BooleanFunction implements Function,ArrayFunction {
|
public abstract class BooleanFunction implements Function,ArrayFunction {
|
||||||
|
|
||||||
|
@ -132,43 +130,12 @@ public abstract class BooleanFunction implements Function,ArrayFunction {
|
||||||
return cumulativeResult || currentValue;
|
return cumulativeResult || currentValue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
public static final Function FALSE = new Fixed0ArgFunction() {
|
|
||||||
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) {
|
|
||||||
return BoolEval.FALSE;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function TRUE = new Fixed0ArgFunction() {
|
|
||||||
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) {
|
|
||||||
return BoolEval.TRUE;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
abstract static class Boolean1ArgFunction extends Fixed1ArgFunction implements ArrayFunction {
|
public static final Function FALSE = BooleanFunction::evaluateFalse;
|
||||||
@Override
|
|
||||||
public ValueEval evaluateArray(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
|
|
||||||
if (args.length != 1) {
|
|
||||||
return ErrorEval.VALUE_INVALID;
|
|
||||||
}
|
|
||||||
return evaluateOneArrayArg(args[0], srcRowIndex, srcColumnIndex,
|
|
||||||
vA -> evaluate(srcRowIndex, srcColumnIndex, vA));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
public static final Function TRUE = BooleanFunction::evaluateTrue;
|
||||||
|
|
||||||
public static final Function NOT = new Boolean1ArgFunction() {
|
public static final Function NOT = BooleanFunction::evaluateNot;
|
||||||
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
|
|
||||||
boolean boolArgVal;
|
|
||||||
try {
|
|
||||||
ValueEval ve = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
|
|
||||||
Boolean b = OperandResolver.coerceValueToBoolean(ve, false);
|
|
||||||
boolArgVal = b == null ? false : b;
|
|
||||||
} catch (EvaluationException e) {
|
|
||||||
return e.getErrorEval();
|
|
||||||
}
|
|
||||||
|
|
||||||
return BoolEval.valueOf(!boolArgVal);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ValueEval evaluateArray(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
|
public ValueEval evaluateArray(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
|
||||||
|
@ -178,4 +145,30 @@ public abstract class BooleanFunction implements Function,ArrayFunction {
|
||||||
return evaluateOneArrayArg(args[0], srcRowIndex, srcColumnIndex,
|
return evaluateOneArrayArg(args[0], srcRowIndex, srcColumnIndex,
|
||||||
vA -> evaluate(new ValueEval[]{vA}, srcRowIndex, srcColumnIndex));
|
vA -> evaluate(new ValueEval[]{vA}, srcRowIndex, srcColumnIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static ValueEval evaluateFalse(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
|
||||||
|
return args.length != 0 ? ErrorEval.VALUE_INVALID : BoolEval.FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ValueEval evaluateTrue(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
|
||||||
|
return args.length != 0 ? ErrorEval.VALUE_INVALID : BoolEval.TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ValueEval evaluateNot(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
|
||||||
|
if (args.length != 1) {
|
||||||
|
return ErrorEval.VALUE_INVALID;
|
||||||
|
}
|
||||||
|
java.util.function.Function<ValueEval, ValueEval> notInner = (va) -> {
|
||||||
|
try {
|
||||||
|
ValueEval ve = OperandResolver.getSingleValue(va, srcRowIndex, srcColumnIndex);
|
||||||
|
Boolean b = OperandResolver.coerceValueToBoolean(ve, false);
|
||||||
|
boolean boolArgVal = b != null && b;
|
||||||
|
return BoolEval.valueOf(!boolArgVal);
|
||||||
|
} catch (EvaluationException e) {
|
||||||
|
return e.getErrorEval();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return ArrayFunction._evaluateOneArrayArg(args[0], srcRowIndex, srcColumnIndex, notInner);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -23,18 +23,19 @@ import org.apache.poi.ss.formula.eval.NumberEval;
|
||||||
import org.apache.poi.ss.formula.eval.RefEval;
|
import org.apache.poi.ss.formula.eval.RefEval;
|
||||||
import org.apache.poi.ss.formula.eval.ValueEval;
|
import org.apache.poi.ss.formula.eval.ValueEval;
|
||||||
|
|
||||||
public final class Column implements Function0Arg, Function1Arg {
|
public final class Column {
|
||||||
|
public static ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
|
||||||
|
if (args.length > 1) {
|
||||||
|
return ErrorEval.VALUE_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) {
|
|
||||||
return new NumberEval(srcColumnIndex+1.);
|
|
||||||
}
|
|
||||||
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
|
|
||||||
int rnum;
|
int rnum;
|
||||||
|
if (args.length == 0) {
|
||||||
if (arg0 instanceof AreaEval) {
|
rnum = srcColumnIndex;
|
||||||
rnum = ((AreaEval) arg0).getFirstColumn();
|
} else if (args[0] instanceof AreaEval) {
|
||||||
} else if (arg0 instanceof RefEval) {
|
rnum = ((AreaEval) args[0]).getFirstColumn();
|
||||||
rnum = ((RefEval) arg0).getColumn();
|
} else if (args[0] instanceof RefEval) {
|
||||||
|
rnum = ((RefEval) args[0]).getColumn();
|
||||||
} else {
|
} else {
|
||||||
// anything else is not valid argument
|
// anything else is not valid argument
|
||||||
return ErrorEval.VALUE_INVALID;
|
return ErrorEval.VALUE_INVALID;
|
||||||
|
@ -42,13 +43,4 @@ public final class Column implements Function0Arg, Function1Arg {
|
||||||
|
|
||||||
return new NumberEval(rnum + 1.);
|
return new NumberEval(rnum + 1.);
|
||||||
}
|
}
|
||||||
public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
|
|
||||||
switch (args.length) {
|
|
||||||
case 1:
|
|
||||||
return evaluate(srcRowIndex, srcColumnIndex, args[0]);
|
|
||||||
case 0:
|
|
||||||
return new NumberEval(srcColumnIndex+1.);
|
|
||||||
}
|
|
||||||
return ErrorEval.VALUE_INVALID;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
/* ====================================================================
|
|
||||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
contributor license agreements. See the NOTICE file distributed with
|
|
||||||
this work for additional information regarding copyright ownership.
|
|
||||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
(the "License"); you may not use this file except in compliance with
|
|
||||||
the License. You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
==================================================================== */
|
|
||||||
|
|
||||||
package org.apache.poi.ss.formula.functions;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public final class Even extends NumericFunction.OneArg {
|
|
||||||
|
|
||||||
private static final long PARITY_MASK = 0xFFFFFFFFFFFFFFFEL;
|
|
||||||
|
|
||||||
protected double evaluate(double d) {
|
|
||||||
if (d==0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
long result;
|
|
||||||
if (d>0) {
|
|
||||||
result = calcEven(d);
|
|
||||||
} else {
|
|
||||||
result = -calcEven(-d);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static long calcEven(double d) {
|
|
||||||
long x = ((long) d) & PARITY_MASK;
|
|
||||||
if (x == d) {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
return x + 2;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -19,12 +19,15 @@ package org.apache.poi.ss.formula.functions;
|
||||||
|
|
||||||
import org.apache.poi.ss.formula.eval.ErrorEval;
|
import org.apache.poi.ss.formula.eval.ErrorEval;
|
||||||
import org.apache.poi.ss.formula.eval.ValueEval;
|
import org.apache.poi.ss.formula.eval.ValueEval;
|
||||||
|
import org.apache.poi.util.Removal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience base class for functions that only take zero arguments.
|
* Convenience base class for functions that only take zero arguments.
|
||||||
*
|
*
|
||||||
* @author Josh Micich
|
* @deprecated replaced by lambda expressions in 5.0.1
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Removal(version = "6.0.0")
|
||||||
public abstract class Fixed0ArgFunction implements Function0Arg {
|
public abstract class Fixed0ArgFunction implements Function0Arg {
|
||||||
public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
|
public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
|
||||||
if (args.length != 0) {
|
if (args.length != 0) {
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
|
||||||
|
package org.apache.poi.ss.formula.functions;
|
||||||
|
|
||||||
|
import org.apache.poi.ss.formula.eval.ErrorEval;
|
||||||
|
import org.apache.poi.ss.formula.eval.EvaluationException;
|
||||||
|
import org.apache.poi.ss.formula.eval.NumberEval;
|
||||||
|
import org.apache.poi.ss.formula.eval.ValueEval;
|
||||||
|
|
||||||
|
public class Log {
|
||||||
|
private static final double TEN = 10.0;
|
||||||
|
private static final double LOG_10_TO_BASE_e = Math.log(TEN);
|
||||||
|
|
||||||
|
public static ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
|
||||||
|
if (args.length != 1 && args.length != 2) {
|
||||||
|
return ErrorEval.VALUE_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
double d0 = NumericFunction.singleOperandEvaluate(args[0], srcRowIndex, srcColumnIndex);
|
||||||
|
double result;
|
||||||
|
if (args.length == 1) {
|
||||||
|
result = Math.log(d0) / LOG_10_TO_BASE_e;
|
||||||
|
} else {
|
||||||
|
double d1 = NumericFunction.singleOperandEvaluate(args[1], srcRowIndex, srcColumnIndex);
|
||||||
|
double logE = Math.log(d0);
|
||||||
|
result = (Double.compare(d1, Math.E) == 0) ? logE : (logE / Math.log(d1));
|
||||||
|
}
|
||||||
|
NumericFunction.checkValue(result);
|
||||||
|
return new NumberEval(result);
|
||||||
|
} catch (EvaluationException e) {
|
||||||
|
return e.getErrorEval();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -51,6 +51,12 @@ final class MathX {
|
||||||
return round(n, p, java.math.RoundingMode.HALF_UP);
|
return round(n, p, java.math.RoundingMode.HALF_UP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static double round(double n, double p) {
|
||||||
|
return round(n, (int)p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a value rounded-up to p digits after decimal.
|
* Returns a value rounded-up to p digits after decimal.
|
||||||
* If p is negative, then the number is rounded to
|
* If p is negative, then the number is rounded to
|
||||||
|
@ -70,6 +76,11 @@ final class MathX {
|
||||||
return round(n, p, java.math.RoundingMode.UP);
|
return round(n, p, java.math.RoundingMode.UP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static double roundUp(double n, double p) {
|
||||||
|
return roundUp(n, (int)p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a value rounded to p digits after decimal.
|
* Returns a value rounded to p digits after decimal.
|
||||||
* If p is negative, then the number is rounded to
|
* If p is negative, then the number is rounded to
|
||||||
|
@ -89,6 +100,10 @@ final class MathX {
|
||||||
return round(n, p, java.math.RoundingMode.DOWN);
|
return round(n, p, java.math.RoundingMode.DOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static double roundDown(double n, double p) {
|
||||||
|
return roundDown(n, (int)p);
|
||||||
|
}
|
||||||
|
|
||||||
private static double round(double n, int p, java.math.RoundingMode rounding) {
|
private static double round(double n, int p, java.math.RoundingMode rounding) {
|
||||||
if (Double.isNaN(n) || Double.isInfinite(n)) {
|
if (Double.isNaN(n) || Double.isInfinite(n)) {
|
||||||
return Double.NaN;
|
return Double.NaN;
|
||||||
|
@ -273,6 +288,10 @@ final class MathX {
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static double factorial(double d) {
|
||||||
|
return factorial((int)d);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns the remainder resulting from operation:
|
* returns the remainder resulting from operation:
|
||||||
|
|
|
@ -22,12 +22,9 @@ import org.apache.poi.ss.formula.eval.ValueEval;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of Excel function NA()
|
* Implementation of Excel function NA()
|
||||||
*
|
|
||||||
* @author Josh Micich
|
|
||||||
*/
|
*/
|
||||||
public final class Na extends Fixed0ArgFunction {
|
public final class Na {
|
||||||
|
public static ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) {
|
||||||
public ValueEval evaluate(int srcCellRow, int srcCellCol) {
|
return args.length != 0 ? ErrorEval.VALUE_INVALID : ErrorEval.NA;
|
||||||
return ErrorEval.NA;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,18 +19,19 @@ package org.apache.poi.ss.formula.functions;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.apache.poi.ss.formula.eval.ErrorEval;
|
||||||
import org.apache.poi.ss.formula.eval.NumberEval;
|
import org.apache.poi.ss.formula.eval.NumberEval;
|
||||||
import org.apache.poi.ss.formula.eval.ValueEval;
|
import org.apache.poi.ss.formula.eval.ValueEval;
|
||||||
import org.apache.poi.ss.usermodel.DateUtil;
|
import org.apache.poi.ss.usermodel.DateUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of Excel NOW() Function
|
* Implementation of Excel NOW() Function
|
||||||
*
|
|
||||||
* @author Frank Taffelt
|
|
||||||
*/
|
*/
|
||||||
public final class Now extends Fixed0ArgFunction {
|
public final class Now {
|
||||||
|
public static ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
|
||||||
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) {
|
if (args.length != 0) {
|
||||||
|
return ErrorEval.VALUE_INVALID;
|
||||||
|
}
|
||||||
Date now = new Date(System.currentTimeMillis());
|
Date now = new Date(System.currentTimeMillis());
|
||||||
return new NumberEval(DateUtil.getExcelDate(now));
|
return new NumberEval(DateUtil.getExcelDate(now));
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,18 +17,17 @@
|
||||||
|
|
||||||
package org.apache.poi.ss.formula.functions;
|
package org.apache.poi.ss.formula.functions;
|
||||||
|
|
||||||
|
import static org.apache.poi.ss.formula.eval.ErrorEval.VALUE_INVALID;
|
||||||
|
|
||||||
import org.apache.poi.ss.formula.eval.*;
|
import org.apache.poi.ss.formula.eval.*;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
|
||||||
* @author Josh Micich
|
|
||||||
* @author Stephen Wolke (smwolke at geistig.com)
|
|
||||||
*/
|
|
||||||
public abstract class NumericFunction implements Function {
|
public abstract class NumericFunction implements Function {
|
||||||
|
|
||||||
static final double ZERO = 0.0;
|
private static final double ZERO = 0.0;
|
||||||
static final double TEN = 10.0;
|
private static final double TEN = 10.0;
|
||||||
static final double LOG_10_TO_BASE_e = Math.log(TEN);
|
private static final double LOG_10_TO_BASE_e = Math.log(TEN);
|
||||||
|
private static final long PARITY_MASK = 0xFFFFFFFFFFFFFFFEL;
|
||||||
|
|
||||||
|
|
||||||
protected static double singleOperandEvaluate(ValueEval arg, int srcRowIndex, int srcColumnIndex) throws EvaluationException {
|
protected static double singleOperandEvaluate(ValueEval arg, int srcRowIndex, int srcColumnIndex) throws EvaluationException {
|
||||||
if (arg == null) {
|
if (arg == null) {
|
||||||
|
@ -41,7 +40,7 @@ public abstract class NumericFunction implements Function {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws EvaluationException (#NUM!) if <tt>result</tt> is <tt>NaN</tt> or <tt>Infinity</tt>
|
* @throws EvaluationException (#NUM!) if <tt>result</tt> is {@code NaN} or {@code Infinity}
|
||||||
*/
|
*/
|
||||||
public static void checkValue(double result) throws EvaluationException {
|
public static void checkValue(double result) throws EvaluationException {
|
||||||
if (Double.isNaN(result) || Double.isInfinite(result)) {
|
if (Double.isNaN(result) || Double.isInfinite(result)) {
|
||||||
|
@ -62,432 +61,179 @@ public abstract class NumericFunction implements Function {
|
||||||
|
|
||||||
protected abstract double eval(ValueEval[] args, int srcCellRow, int srcCellCol) throws EvaluationException;
|
protected abstract double eval(ValueEval[] args, int srcCellRow, int srcCellCol) throws EvaluationException;
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
public static final Function ABS = oneDouble(Math::abs);
|
||||||
// intermediate sub-classes (one-arg, two-arg and multi-arg)
|
public static final Function ACOS = oneDouble(Math::acos);
|
||||||
|
public static final Function ACOSH = oneDouble(MathX::acosh);
|
||||||
|
public static final Function ASIN = oneDouble(Math::asin);
|
||||||
|
public static final Function ASINH = oneDouble(MathX::asinh);
|
||||||
|
public static final Function ATAN = oneDouble(Math::atan);
|
||||||
|
public static final Function ATANH = oneDouble(MathX::atanh);
|
||||||
|
public static final Function COS = oneDouble(Math::cos);
|
||||||
|
public static final Function COSH = oneDouble(MathX::cosh);
|
||||||
|
public static final Function DEGREES = oneDouble(Math::toDegrees);
|
||||||
|
public static final Function DOLLAR = NumericFunction::evaluateDollar;
|
||||||
|
|
||||||
public static abstract class OneArg extends Fixed1ArgFunction {
|
private static ValueEval evaluateDollar(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
|
||||||
protected OneArg() {
|
if (args.length != 1 && args.length != 2) {
|
||||||
// no fields to initialise
|
return ErrorEval.VALUE_INVALID;
|
||||||
}
|
}
|
||||||
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
|
try {
|
||||||
double result;
|
double val = singleOperandEvaluate(args[0], srcRowIndex, srcColumnIndex);
|
||||||
try {
|
double d1 = args.length == 1 ? 2.0 : singleOperandEvaluate(args[1], srcRowIndex, srcColumnIndex);
|
||||||
double d = singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex);
|
|
||||||
result = evaluate(d);
|
|
||||||
checkValue(result);
|
|
||||||
} catch (EvaluationException e) {
|
|
||||||
return e.getErrorEval();
|
|
||||||
}
|
|
||||||
return new NumberEval(result);
|
|
||||||
}
|
|
||||||
protected final double eval(ValueEval[] args, int srcCellRow, int srcCellCol) throws EvaluationException {
|
|
||||||
if (args.length != 1) {
|
|
||||||
throw new EvaluationException(ErrorEval.VALUE_INVALID);
|
|
||||||
}
|
|
||||||
double d = singleOperandEvaluate(args[0], srcCellRow, srcCellCol);
|
|
||||||
return evaluate(d);
|
|
||||||
}
|
|
||||||
protected abstract double evaluate(double d) throws EvaluationException;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static abstract class TwoArg extends Fixed2ArgFunction {
|
|
||||||
protected TwoArg() {
|
|
||||||
// no fields to initialise
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
|
|
||||||
double result;
|
|
||||||
try {
|
|
||||||
double d0 = singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex);
|
|
||||||
double d1 = singleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex);
|
|
||||||
result = evaluate(d0, d1);
|
|
||||||
checkValue(result);
|
|
||||||
} catch (EvaluationException e) {
|
|
||||||
return e.getErrorEval();
|
|
||||||
}
|
|
||||||
return new NumberEval(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract double evaluate(double d0, double d1) throws EvaluationException;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
public static final Function ABS = new OneArg() {
|
|
||||||
protected double evaluate(double d) {
|
|
||||||
return Math.abs(d);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function ACOS = new OneArg() {
|
|
||||||
protected double evaluate(double d) {
|
|
||||||
return Math.acos(d);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function ACOSH = new OneArg() {
|
|
||||||
protected double evaluate(double d) {
|
|
||||||
return MathX.acosh(d);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function ASIN = new OneArg() {
|
|
||||||
protected double evaluate(double d) {
|
|
||||||
return Math.asin(d);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function ASINH = new OneArg() {
|
|
||||||
protected double evaluate(double d) {
|
|
||||||
return MathX.asinh(d);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function ATAN = new OneArg() {
|
|
||||||
protected double evaluate(double d) {
|
|
||||||
return Math.atan(d);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function ATANH = new OneArg() {
|
|
||||||
protected double evaluate(double d) {
|
|
||||||
return MathX.atanh(d);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function COS = new OneArg() {
|
|
||||||
protected double evaluate(double d) {
|
|
||||||
return Math.cos(d);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function COSH = new OneArg() {
|
|
||||||
protected double evaluate(double d) {
|
|
||||||
return MathX.cosh(d);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function DEGREES = new OneArg() {
|
|
||||||
protected double evaluate(double d) {
|
|
||||||
return Math.toDegrees(d);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
static final NumberEval DOLLAR_ARG2_DEFAULT = new NumberEval(2.0);
|
|
||||||
public static final Function DOLLAR = new Var1or2ArgFunction() {
|
|
||||||
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
|
|
||||||
return evaluate(srcRowIndex, srcColumnIndex, arg0, DOLLAR_ARG2_DEFAULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0,
|
|
||||||
ValueEval arg1) {
|
|
||||||
double val;
|
|
||||||
double d1;
|
|
||||||
try {
|
|
||||||
val = singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex);
|
|
||||||
d1 = singleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex);
|
|
||||||
} catch (EvaluationException e) {
|
|
||||||
return e.getErrorEval();
|
|
||||||
}
|
|
||||||
// second arg converts to int by truncating toward zero
|
// second arg converts to int by truncating toward zero
|
||||||
int nPlaces = (int)d1;
|
int nPlaces = (int)d1;
|
||||||
|
|
||||||
if (nPlaces > 127) {
|
if (nPlaces > 127) {
|
||||||
return ErrorEval.VALUE_INVALID;
|
return VALUE_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO - DOLLAR() function impl is NQR
|
// TODO - DOLLAR() function impl is NQR
|
||||||
// result should be StringEval, with leading '$' and thousands separators
|
// result should be StringEval, with leading '$' and thousands separators
|
||||||
// current junits are asserting incorrect behaviour
|
// current junits are asserting incorrect behaviour
|
||||||
return new NumberEval(val);
|
return new NumberEval(val);
|
||||||
}
|
}catch (EvaluationException e) {
|
||||||
};
|
return e.getErrorEval();
|
||||||
public static final Function EXP = new OneArg() {
|
|
||||||
protected double evaluate(double d) {
|
|
||||||
return Math.pow(Math.E, d);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function FACT = new OneArg() {
|
|
||||||
protected double evaluate(double d) {
|
|
||||||
return MathX.factorial((int)d);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function INT = new OneArg() {
|
|
||||||
protected double evaluate(double d) {
|
|
||||||
return Math.round(d-0.5);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function LN = new OneArg() {
|
|
||||||
protected double evaluate(double d) {
|
|
||||||
return Math.log(d);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function LOG10 = new OneArg() {
|
|
||||||
protected double evaluate(double d) {
|
|
||||||
return Math.log(d) / LOG_10_TO_BASE_e;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function RADIANS = new OneArg() {
|
|
||||||
protected double evaluate(double d) {
|
|
||||||
return Math.toRadians(d);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function SIGN = new OneArg() {
|
|
||||||
protected double evaluate(double d) {
|
|
||||||
return MathX.sign(d);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function SIN = new OneArg() {
|
|
||||||
protected double evaluate(double d) {
|
|
||||||
return Math.sin(d);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function SINH = new OneArg() {
|
|
||||||
protected double evaluate(double d) {
|
|
||||||
return MathX.sinh(d);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function SQRT = new OneArg() {
|
|
||||||
protected double evaluate(double d) {
|
|
||||||
return Math.sqrt(d);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public static final Function TAN = new OneArg() {
|
|
||||||
protected double evaluate(double d) {
|
|
||||||
return Math.tan(d);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function TANH = new OneArg() {
|
|
||||||
protected double evaluate(double d) {
|
|
||||||
return MathX.tanh(d);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
public static final Function ATAN2 = new TwoArg() {
|
|
||||||
protected double evaluate(double d0, double d1) throws EvaluationException {
|
|
||||||
if (d0 == ZERO && d1 == ZERO) {
|
|
||||||
throw new EvaluationException(ErrorEval.DIV_ZERO);
|
|
||||||
}
|
|
||||||
return Math.atan2(d1, d0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function CEILING = new TwoArg() {
|
|
||||||
protected double evaluate(double d0, double d1) {
|
|
||||||
return MathX.ceiling(d0, d1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function COMBIN = new TwoArg() {
|
|
||||||
protected double evaluate(double d0, double d1) throws EvaluationException {
|
|
||||||
if (d0 > Integer.MAX_VALUE || d1 > Integer.MAX_VALUE) {
|
|
||||||
throw new EvaluationException(ErrorEval.NUM_ERROR);
|
|
||||||
}
|
|
||||||
return MathX.nChooseK((int) d0, (int) d1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function FLOOR = new TwoArg() {
|
|
||||||
protected double evaluate(double d0, double d1) throws EvaluationException {
|
|
||||||
if (d1 == ZERO) {
|
|
||||||
if (d0 == ZERO) {
|
|
||||||
return ZERO;
|
|
||||||
}
|
|
||||||
throw new EvaluationException(ErrorEval.DIV_ZERO);
|
|
||||||
}
|
|
||||||
return MathX.floor(d0, d1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function MOD = new TwoArg() {
|
|
||||||
protected double evaluate(double d0, double d1) throws EvaluationException {
|
|
||||||
if (d1 == ZERO) {
|
|
||||||
throw new EvaluationException(ErrorEval.DIV_ZERO);
|
|
||||||
}
|
|
||||||
return MathX.mod(d0, d1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function POWER = new TwoArg() {
|
|
||||||
protected double evaluate(double d0, double d1) {
|
|
||||||
return Math.pow(d0, d1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function ROUND = new TwoArg() {
|
|
||||||
protected double evaluate(double d0, double d1) {
|
|
||||||
return MathX.round(d0, (int)d1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function ROUNDDOWN = new TwoArg() {
|
|
||||||
protected double evaluate(double d0, double d1) {
|
|
||||||
return MathX.roundDown(d0, (int)d1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public static final Function ROUNDUP = new TwoArg() {
|
|
||||||
protected double evaluate(double d0, double d1) {
|
|
||||||
return MathX.roundUp(d0, (int)d1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
static final NumberEval TRUNC_ARG2_DEFAULT = new NumberEval(0);
|
|
||||||
public static final Function TRUNC = new Var1or2ArgFunction() {
|
|
||||||
|
|
||||||
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
|
|
||||||
return evaluate(srcRowIndex, srcColumnIndex, arg0, TRUNC_ARG2_DEFAULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
|
|
||||||
double result;
|
|
||||||
try {
|
|
||||||
double d0 = singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex);
|
|
||||||
double d1 = singleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex);
|
|
||||||
result = MathX.roundDown(d0, (int)d1);
|
|
||||||
checkValue(result);
|
|
||||||
}catch (EvaluationException e) {
|
|
||||||
return e.getErrorEval();
|
|
||||||
}
|
|
||||||
return new NumberEval(result);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
private static final class Log extends Var1or2ArgFunction {
|
|
||||||
public Log() {
|
|
||||||
// no instance fields
|
|
||||||
}
|
|
||||||
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
|
|
||||||
double result;
|
|
||||||
try {
|
|
||||||
double d0 = NumericFunction.singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex);
|
|
||||||
result = Math.log(d0) / LOG_10_TO_BASE_e;
|
|
||||||
NumericFunction.checkValue(result);
|
|
||||||
} catch (EvaluationException e) {
|
|
||||||
return e.getErrorEval();
|
|
||||||
}
|
|
||||||
return new NumberEval(result);
|
|
||||||
}
|
|
||||||
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0,
|
|
||||||
ValueEval arg1) {
|
|
||||||
double result;
|
|
||||||
try {
|
|
||||||
double d0 = NumericFunction.singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex);
|
|
||||||
double d1 = NumericFunction.singleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex);
|
|
||||||
double logE = Math.log(d0);
|
|
||||||
if (Double.compare(d1, Math.E) == 0) {
|
|
||||||
result = logE;
|
|
||||||
} else {
|
|
||||||
result = logE / Math.log(d1);
|
|
||||||
}
|
|
||||||
NumericFunction.checkValue(result);
|
|
||||||
} catch (EvaluationException e) {
|
|
||||||
return e.getErrorEval();
|
|
||||||
}
|
|
||||||
return new NumberEval(result);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Function LOG = new Log();
|
public static final Function EXP = oneDouble(d -> Math.pow(Math.E, d));
|
||||||
|
public static final Function FACT = oneDouble(MathX::factorial);
|
||||||
|
public static final Function INT = oneDouble(d -> Math.round(d-0.5));
|
||||||
|
public static final Function LN = oneDouble(Math::log);
|
||||||
|
public static final Function LOG10 = oneDouble(d -> Math.log(d) / LOG_10_TO_BASE_e);
|
||||||
|
public static final Function RADIANS = oneDouble(Math::toRadians);
|
||||||
|
public static final Function SIGN = oneDouble(MathX::sign);
|
||||||
|
public static final Function SIN = oneDouble(Math::sin);
|
||||||
|
public static final Function SINH = oneDouble(MathX::sinh);
|
||||||
|
public static final Function SQRT = oneDouble(Math::sqrt);
|
||||||
|
public static final Function TAN = oneDouble(Math::tan);
|
||||||
|
public static final Function TANH = oneDouble(MathX::tanh);
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
public static final Function ATAN2 = twoDouble((d0, d1) ->
|
||||||
|
(d0 == ZERO && d1 == ZERO) ? ErrorEval.DIV_ZERO : Math.atan2(d1, d0)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final Function CEILING = twoDouble(MathX::ceiling);
|
||||||
|
|
||||||
|
public static final Function COMBIN = twoDouble((d0, d1) ->
|
||||||
|
(d0 > Integer.MAX_VALUE || d1 > Integer.MAX_VALUE) ? ErrorEval.NUM_ERROR : MathX.nChooseK((int) d0, (int) d1));
|
||||||
|
|
||||||
|
public static final Function FLOOR = twoDouble((d0, d1) ->
|
||||||
|
(d1 == ZERO) ? (d0 == ZERO ? ZERO : ErrorEval.DIV_ZERO) : MathX.floor(d0, d1));
|
||||||
|
|
||||||
|
public static final Function MOD = twoDouble((d0, d1) ->
|
||||||
|
(d1 == ZERO) ? ErrorEval.DIV_ZERO : MathX.mod(d0, d1));
|
||||||
|
|
||||||
|
public static final Function POWER = twoDouble(Math::pow);
|
||||||
|
|
||||||
|
public static final Function ROUND = twoDouble(MathX::round);
|
||||||
|
public static final Function ROUNDDOWN = twoDouble(MathX::roundDown);
|
||||||
|
public static final Function ROUNDUP = twoDouble(MathX::roundUp);
|
||||||
|
public static final Function TRUNC = NumericFunction::evaluateTrunc;
|
||||||
|
|
||||||
|
private static ValueEval evaluateTrunc(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
|
||||||
|
if (args.length != 1 && args.length != 2) {
|
||||||
|
return ErrorEval.VALUE_INVALID;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
double d0 = singleOperandEvaluate(args[0], srcRowIndex, srcColumnIndex);
|
||||||
|
double d1 = args.length == 1 ? 0 : singleOperandEvaluate(args[1], srcRowIndex, srcColumnIndex);
|
||||||
|
double result = MathX.roundDown(d0, d1);
|
||||||
|
checkValue(result);
|
||||||
|
return new NumberEval(result);
|
||||||
|
}catch (EvaluationException e) {
|
||||||
|
return e.getErrorEval();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
public static final Function LOG = Log::evaluate;
|
||||||
|
|
||||||
static final NumberEval PI_EVAL = new NumberEval(Math.PI);
|
static final NumberEval PI_EVAL = new NumberEval(Math.PI);
|
||||||
public static final Function PI = new Fixed0ArgFunction() {
|
public static final Function PI = NumericFunction::evaluatePI;
|
||||||
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) {
|
|
||||||
return PI_EVAL;
|
private static ValueEval evaluatePI(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
|
||||||
|
return (args.length != 0) ? ErrorEval.VALUE_INVALID : PI_EVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Function RAND = NumericFunction::evaluateRand;
|
||||||
|
|
||||||
|
private static ValueEval evaluateRand(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
|
||||||
|
return (args.length != 0) ? ErrorEval.VALUE_INVALID : new NumberEval(Math.random());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Function POISSON = Poisson::evaluate;
|
||||||
|
|
||||||
|
public static final Function ODD = oneDouble(NumericFunction::evaluateOdd);
|
||||||
|
|
||||||
|
private static double evaluateOdd(double d) {
|
||||||
|
if (d==0) {
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
};
|
double dpm = Math.abs(d)+1;
|
||||||
public static final Function RAND = new Fixed0ArgFunction() {
|
long x = ((long) dpm) & PARITY_MASK;
|
||||||
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) {
|
return MathX.sign(d) * ((Double.compare(x, dpm) == 0) ? x-1 : x+1);
|
||||||
return new NumberEval(Math.random());
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static final Function EVEN = oneDouble(NumericFunction::evaluateEven);
|
||||||
|
|
||||||
|
private static double evaluateEven(double d) {
|
||||||
|
if (d==0) {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
public static final Function POISSON = new Fixed3ArgFunction() {
|
|
||||||
|
|
||||||
private static final double DEFAULT_RETURN_RESULT =1;
|
double dpm = Math.abs(d);
|
||||||
|
long x = ((long) dpm) & PARITY_MASK;
|
||||||
/**
|
return MathX.sign(d) * ((Double.compare(x, dpm) == 0) ? x : (x + 2));
|
||||||
* This checks is x = 0 and the mean = 0.
|
}
|
||||||
* Excel currently returns the value 1 where as the
|
|
||||||
* maths common implementation will error.
|
|
||||||
* @param x The number.
|
|
||||||
* @param mean The mean.
|
|
||||||
* @return If a default value should be returned.
|
|
||||||
*/
|
|
||||||
private boolean isDefaultResult(double x, double mean) {
|
|
||||||
|
|
||||||
if ( x == 0 && mean == 0 ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean checkArgument(double aDouble) throws EvaluationException {
|
|
||||||
|
|
||||||
NumericFunction.checkValue(aDouble);
|
|
||||||
|
|
||||||
// make sure that the number is positive
|
|
||||||
if (aDouble < 0) {
|
|
||||||
throw new EvaluationException(ErrorEval.NUM_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private double probability(int k, double lambda) {
|
|
||||||
return Math.pow(lambda, k) * Math.exp(-lambda) / factorial(k);
|
|
||||||
}
|
|
||||||
|
|
||||||
private double cumulativeProbability(int x, double lambda) {
|
|
||||||
double result = 0;
|
|
||||||
for(int k = 0; k <= x; k++){
|
|
||||||
result += probability(k, lambda);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** All long-representable factorials */
|
|
||||||
private final long[] FACTORIALS = new long[] {
|
|
||||||
1l, 1l, 2l,
|
|
||||||
6l, 24l, 120l,
|
|
||||||
720l, 5040l, 40320l,
|
|
||||||
362880l, 3628800l, 39916800l,
|
|
||||||
479001600l, 6227020800l, 87178291200l,
|
|
||||||
1307674368000l, 20922789888000l, 355687428096000l,
|
|
||||||
6402373705728000l, 121645100408832000l, 2432902008176640000l };
|
|
||||||
|
|
||||||
|
|
||||||
public long factorial(final int n) {
|
private interface OneDoubleIf {
|
||||||
if (n < 0 || n > 20) {
|
double apply(double d);
|
||||||
throw new IllegalArgumentException("Valid argument should be in the range [0..20]");
|
}
|
||||||
}
|
|
||||||
return FACTORIALS[n];
|
|
||||||
}
|
|
||||||
|
|
||||||
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, ValueEval arg2) {
|
|
||||||
|
|
||||||
// arguments/result for this function
|
|
||||||
double mean=0;
|
|
||||||
double x=0;
|
|
||||||
boolean cumulative = ((BoolEval)arg2).getBooleanValue();
|
|
||||||
double result=0;
|
|
||||||
|
|
||||||
try {
|
|
||||||
x = NumericFunction.singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex);
|
|
||||||
mean = NumericFunction.singleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex);
|
|
||||||
|
|
||||||
// check for default result : excel implementation for 0,0
|
|
||||||
// is different to Math Common.
|
|
||||||
if (isDefaultResult(x,mean)) {
|
|
||||||
return new NumberEval(DEFAULT_RETURN_RESULT);
|
|
||||||
}
|
|
||||||
// check the arguments : as per excel function def
|
|
||||||
checkArgument(x);
|
|
||||||
checkArgument(mean);
|
|
||||||
|
|
||||||
// truncate x : as per excel function def
|
|
||||||
if ( cumulative ) {
|
|
||||||
result = cumulativeProbability((int)x, mean);
|
|
||||||
} else {
|
|
||||||
result = probability((int)x, mean);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check the result
|
|
||||||
NumericFunction.checkValue(result);
|
|
||||||
|
|
||||||
|
private static Function oneDouble(OneDoubleIf doubleFun) {
|
||||||
|
return (args, srcCellRow, srcCellCol) -> {
|
||||||
|
if (args.length != 1) {
|
||||||
|
return VALUE_INVALID;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
double d = singleOperandEvaluate(args[0], srcCellRow, srcCellCol);
|
||||||
|
double res = doubleFun.apply(d);
|
||||||
|
return (Double.isNaN(res) || Double.isInfinite(res)) ? ErrorEval.NUM_ERROR : new NumberEval(res);
|
||||||
} catch (EvaluationException e) {
|
} catch (EvaluationException e) {
|
||||||
return e.getErrorEval();
|
return e.getErrorEval();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return new NumberEval(result);
|
private interface TwoDoubleIf {
|
||||||
|
Object apply(double d1, double d2);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
private static Function twoDouble(TwoDoubleIf doubleFun) {
|
||||||
};
|
return (args, srcCellRow, srcCellCol) -> {
|
||||||
|
if (args.length != 2) {
|
||||||
|
return VALUE_INVALID;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
double d1 = singleOperandEvaluate(args[0], srcCellRow, srcCellCol);
|
||||||
|
double d2 = singleOperandEvaluate(args[1], srcCellRow, srcCellCol);
|
||||||
|
Object res = doubleFun.apply(d1, d2);
|
||||||
|
if (res instanceof ErrorEval) {
|
||||||
|
return (ErrorEval)res;
|
||||||
|
}
|
||||||
|
assert(res instanceof Double);
|
||||||
|
double d = (Double)res;
|
||||||
|
return (Double.isNaN(d) || Double.isInfinite(d)) ? ErrorEval.NUM_ERROR : new NumberEval(d);
|
||||||
|
} catch (EvaluationException e) {
|
||||||
|
return e.getErrorEval();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
/* ====================================================================
|
|
||||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
contributor license agreements. See the NOTICE file distributed with
|
|
||||||
this work for additional information regarding copyright ownership.
|
|
||||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
(the "License"); you may not use this file except in compliance with
|
|
||||||
the License. You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
==================================================================== */
|
|
||||||
|
|
||||||
package org.apache.poi.ss.formula.functions;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public final class Odd extends NumericFunction.OneArg {
|
|
||||||
private static final long PARITY_MASK = 0xFFFFFFFFFFFFFFFEL;
|
|
||||||
|
|
||||||
protected double evaluate(double d) {
|
|
||||||
if (d==0) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return (d>0) ? calcOdd(d) : -calcOdd(-d);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static long calcOdd(double d) {
|
|
||||||
double dpm1 = d+1;
|
|
||||||
long x = ((long) dpm1) & PARITY_MASK;
|
|
||||||
return ( Double.compare(x, dpm1) == 0 ) ? x-1 : x+1;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
|
||||||
|
package org.apache.poi.ss.formula.functions;
|
||||||
|
|
||||||
|
import org.apache.poi.ss.formula.eval.BoolEval;
|
||||||
|
import org.apache.poi.ss.formula.eval.ErrorEval;
|
||||||
|
import org.apache.poi.ss.formula.eval.EvaluationException;
|
||||||
|
import org.apache.poi.ss.formula.eval.NumberEval;
|
||||||
|
import org.apache.poi.ss.formula.eval.ValueEval;
|
||||||
|
|
||||||
|
public class Poisson {
|
||||||
|
|
||||||
|
private static final double DEFAULT_RETURN_RESULT =1;
|
||||||
|
|
||||||
|
/** All long-representable factorials */
|
||||||
|
private static final long[] FACTORIALS = {
|
||||||
|
1L, 1L, 2L,
|
||||||
|
6L, 24L, 120L,
|
||||||
|
720L, 5040L, 40320L,
|
||||||
|
362880L, 3628800L, 39916800L,
|
||||||
|
479001600L, 6227020800L, 87178291200L,
|
||||||
|
1307674368000L, 20922789888000L, 355687428096000L,
|
||||||
|
6402373705728000L, 121645100408832000L, 2432902008176640000L };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This checks is x = 0 and the mean = 0.
|
||||||
|
* Excel currently returns the value 1 where as the
|
||||||
|
* maths common implementation will error.
|
||||||
|
* @param x The number.
|
||||||
|
* @param mean The mean.
|
||||||
|
* @return If a default value should be returned.
|
||||||
|
*/
|
||||||
|
private static boolean isDefaultResult(double x, double mean) {
|
||||||
|
return x == 0 && mean == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkArgument(double aDouble) throws EvaluationException {
|
||||||
|
NumericFunction.checkValue(aDouble);
|
||||||
|
|
||||||
|
// make sure that the number is positive
|
||||||
|
if (aDouble < 0) {
|
||||||
|
throw new EvaluationException(ErrorEval.NUM_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double probability(int k, double lambda) {
|
||||||
|
return Math.pow(lambda, k) * Math.exp(-lambda) / factorial(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double cumulativeProbability(int x, double lambda) {
|
||||||
|
double result = 0;
|
||||||
|
for(int k = 0; k <= x; k++){
|
||||||
|
result += probability(k, lambda);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long factorial(final int n) {
|
||||||
|
if (n < 0 || n > 20) {
|
||||||
|
throw new IllegalArgumentException("Valid argument should be in the range [0..20]");
|
||||||
|
}
|
||||||
|
return FACTORIALS[n];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
|
||||||
|
if (args.length != 3) {
|
||||||
|
return ErrorEval.VALUE_INVALID;
|
||||||
|
}
|
||||||
|
ValueEval arg0 = args[0];
|
||||||
|
ValueEval arg1 = args[1];
|
||||||
|
ValueEval arg2 = args[2];
|
||||||
|
|
||||||
|
try {
|
||||||
|
// arguments/result for this function
|
||||||
|
double x = NumericFunction.singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex);
|
||||||
|
double mean = NumericFunction.singleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex);
|
||||||
|
|
||||||
|
// check for default result : excel implementation for 0,0
|
||||||
|
// is different to Math Common.
|
||||||
|
if (isDefaultResult(x,mean)) {
|
||||||
|
return new NumberEval(DEFAULT_RETURN_RESULT);
|
||||||
|
}
|
||||||
|
// check the arguments : as per excel function def
|
||||||
|
checkArgument(x);
|
||||||
|
checkArgument(mean);
|
||||||
|
|
||||||
|
// truncate x : as per excel function def
|
||||||
|
boolean cumulative = ((BoolEval)arg2).getBooleanValue();
|
||||||
|
double result = cumulative ? cumulativeProbability((int) x, mean) : probability((int) x, mean);
|
||||||
|
|
||||||
|
// check the result
|
||||||
|
NumericFunction.checkValue(result);
|
||||||
|
|
||||||
|
return new NumberEval(result);
|
||||||
|
} catch (EvaluationException e) {
|
||||||
|
return e.getErrorEval();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -26,18 +26,19 @@ import org.apache.poi.ss.formula.eval.ValueEval;
|
||||||
/**
|
/**
|
||||||
* Implementation for the Excel function ROW
|
* Implementation for the Excel function ROW
|
||||||
*/
|
*/
|
||||||
public final class RowFunc implements Function0Arg, Function1Arg {
|
public final class RowFunc {
|
||||||
|
public static ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
|
||||||
|
if (args.length > 1) {
|
||||||
|
return ErrorEval.VALUE_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) {
|
|
||||||
return new NumberEval(srcRowIndex+1.);
|
|
||||||
}
|
|
||||||
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
|
|
||||||
int rnum;
|
int rnum;
|
||||||
|
if (args.length == 0) {
|
||||||
if (arg0 instanceof AreaEval) {
|
rnum = srcRowIndex;
|
||||||
rnum = ((AreaEval) arg0).getFirstRow();
|
} else if (args[0] instanceof AreaEval) {
|
||||||
} else if (arg0 instanceof RefEval) {
|
rnum = ((AreaEval) args[0]).getFirstRow();
|
||||||
rnum = ((RefEval) arg0).getRow();
|
} else if (args[0] instanceof RefEval) {
|
||||||
|
rnum = ((RefEval) args[0]).getRow();
|
||||||
} else {
|
} else {
|
||||||
// anything else is not valid argument
|
// anything else is not valid argument
|
||||||
return ErrorEval.VALUE_INVALID;
|
return ErrorEval.VALUE_INVALID;
|
||||||
|
@ -45,13 +46,4 @@ public final class RowFunc implements Function0Arg, Function1Arg {
|
||||||
|
|
||||||
return new NumberEval(rnum + 1.);
|
return new NumberEval(rnum + 1.);
|
||||||
}
|
}
|
||||||
public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
|
|
||||||
switch (args.length) {
|
|
||||||
case 1:
|
|
||||||
return evaluate(srcRowIndex, srcColumnIndex, args[0]);
|
|
||||||
case 0:
|
|
||||||
return new NumberEval(srcRowIndex+1.);
|
|
||||||
}
|
|
||||||
return ErrorEval.VALUE_INVALID;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.ss.formula.functions;
|
||||||
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
import org.apache.poi.ss.formula.eval.ErrorEval;
|
||||||
import org.apache.poi.ss.formula.eval.NumberEval;
|
import org.apache.poi.ss.formula.eval.NumberEval;
|
||||||
import org.apache.poi.ss.formula.eval.ValueEval;
|
import org.apache.poi.ss.formula.eval.ValueEval;
|
||||||
import org.apache.poi.ss.usermodel.DateUtil;
|
import org.apache.poi.ss.usermodel.DateUtil;
|
||||||
|
@ -27,8 +28,11 @@ import org.apache.poi.util.LocaleUtil;
|
||||||
/**
|
/**
|
||||||
* Implementation of Excel TODAY() Function<br>
|
* Implementation of Excel TODAY() Function<br>
|
||||||
*/
|
*/
|
||||||
public final class Today extends Fixed0ArgFunction {
|
public final class Today {
|
||||||
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) {
|
public static ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
|
||||||
|
if (args.length != 0) {
|
||||||
|
return ErrorEval.VALUE_INVALID;
|
||||||
|
}
|
||||||
Calendar now = LocaleUtil.getLocaleCalendar();
|
Calendar now = LocaleUtil.getLocaleCalendar();
|
||||||
now.clear(Calendar.HOUR);
|
now.clear(Calendar.HOUR);
|
||||||
now.set(Calendar.HOUR_OF_DAY,0);
|
now.set(Calendar.HOUR_OF_DAY,0);
|
||||||
|
|
|
@ -24,14 +24,12 @@ import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for ROW(), ROWS(), COLUMN(), COLUMNS()
|
* Tests for ROW(), ROWS(), COLUMN(), COLUMNS()
|
||||||
*
|
|
||||||
* @author Josh Micich
|
|
||||||
*/
|
*/
|
||||||
final class TestRowCol {
|
final class TestRowCol {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCol() {
|
void testCol() {
|
||||||
Function target = new Column();
|
Function target = Column::evaluate;
|
||||||
{
|
{
|
||||||
ValueEval[] args = { EvalFactory.createRefEval("C5"), };
|
ValueEval[] args = { EvalFactory.createRefEval("C5"), };
|
||||||
double actual = NumericFunctionInvoker.invoke(target, args);
|
double actual = NumericFunctionInvoker.invoke(target, args);
|
||||||
|
@ -46,7 +44,7 @@ final class TestRowCol {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testRow() {
|
void testRow() {
|
||||||
Function target = new RowFunc();
|
Function target = RowFunc::evaluate;
|
||||||
{
|
{
|
||||||
ValueEval[] args = { EvalFactory.createRefEval("C5"), };
|
ValueEval[] args = { EvalFactory.createRefEval("C5"), };
|
||||||
double actual = NumericFunctionInvoker.invoke(target, args);
|
double actual = NumericFunctionInvoker.invoke(target, args);
|
||||||
|
|
Loading…
Reference in New Issue