]> source.dussan.org Git - poi.git/commitdiff
fix negative X on T.DIST.RT
authorPJ Fanning <fanningpj@apache.org>
Fri, 22 Oct 2021 09:03:46 +0000 (09:03 +0000)
committerPJ Fanning <fanningpj@apache.org>
Fri, 22 Oct 2021 09:03:46 +0000 (09:03 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1894469 13f79535-47bb-0310-9956-ffa450edef68

poi/src/main/java/org/apache/poi/ss/formula/atp/AnalysisToolPak.java
poi/src/main/java/org/apache/poi/ss/formula/functions/TDistLt.java [new file with mode: 0644]
poi/src/main/java/org/apache/poi/ss/formula/functions/TDistRt.java
poi/src/test/java/org/apache/poi/ss/formula/functions/TestTDistRt.java

index 6647eb581a37465bd227a2ed1c155c5e79623369..8768cb66783acc5f7119f4b8cc2e2226658dbedb 100644 (file)
@@ -173,6 +173,7 @@ public final class AnalysisToolPak implements UDFFinder {
         r(m, "TBILLEQ", null);
         r(m, "TBILLPRICE", null);
         r(m, "TBILLYIELD", null);
+        r(m, "T.DIST", TDistLt.instance);
         r(m, "T.DIST.2T", TDist2t.instance);
         r(m, "T.DIST.RT", TDistRt.instance);
         r(m, "TEXTJOIN", TextJoinFunction.instance);
diff --git a/poi/src/main/java/org/apache/poi/ss/formula/functions/TDistLt.java b/poi/src/main/java/org/apache/poi/ss/formula/functions/TDistLt.java
new file mode 100644 (file)
index 0000000..e5f9b14
--- /dev/null
@@ -0,0 +1,87 @@
+/* ====================================================================
+   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.OperationEvaluationContext;
+import org.apache.poi.ss.formula.eval.*;
+
+/**
+ * Implementation for Excel T.DIST() function.
+ * <p>
+ * <b>Syntax</b>:<br> <b>T.DIST </b>(<b>X</b>,<b>Deg_freedom</b>,<b>Cumulative</b>)<br>
+ * <p>
+ * Returns the Student's left-tailed t-distribution.
+ *
+ * The t-distribution is used in the hypothesis testing of small sample data sets.
+ * Use this function in place of a table of critical values for the t-distribution.
+ *
+ * <ul>
+ *     <li>X     Required. The numeric value at which to evaluate the distribution.</li>
+ *     <li>Deg_freedom     Required. An integer indicating the number of degrees of freedom.</li>
+ *     <li>Cumulative      Required. A logical value that determines the form of the function. If cumulative is TRUE,
+ *     T.DIST returns the cumulative distribution function; if FALSE, it returns the probability density function.</li>
+ * </ul>
+ *
+ * <ul>
+ *     <li>If any argument is non-numeric, T.DIST returns the #VALUE! error value.</li>
+ *     <li>If Deg_freedom &lt; 1, T.DIST returns the #NUM! error value.</li>
+ *     <li>The Deg_freedom argument is truncated to an integer.
+ * </ul>
+ *
+ * https://support.microsoft.com/en-us/office/t-dist-rt-function-20a30020-86f9-4b35-af1f-7ef6ae683eda
+ */
+public final class TDistLt extends Fixed3ArgFunction implements FreeRefFunction {
+
+    public static final TDistLt instance = new TDistLt();
+
+    @Override
+    public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg1, ValueEval arg2, ValueEval arg3) {
+        try {
+            Double number1 = evaluateValue(arg1, srcRowIndex, srcColumnIndex);
+            if (number1 == null) {
+                return ErrorEval.VALUE_INVALID;
+            }
+            Double number2 = evaluateValue(arg2, srcRowIndex, srcColumnIndex);
+            if (number2 == null) {
+                return ErrorEval.VALUE_INVALID;
+            }
+            int degreesOfFreedom = number2.intValue();
+            if (degreesOfFreedom < 1) {
+                return ErrorEval.NUM_ERROR;
+            }
+            return new NumberEval(TDist.tdistOneTail(Math.abs(number1), degreesOfFreedom));
+        } catch (EvaluationException e) {
+            return e.getErrorEval();
+        }
+    }
+
+    @Override
+    public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) {
+         if (args.length == 3) {
+            return evaluate(ec.getRowIndex(), ec.getColumnIndex(), args[0], args[1], args[2]);
+        }
+
+        return ErrorEval.VALUE_INVALID;
+    }
+
+    private static Double evaluateValue(ValueEval arg, int srcRowIndex, int srcColumnIndex) throws EvaluationException {
+        ValueEval veText = OperandResolver.getSingleValue(arg, srcRowIndex, srcColumnIndex);
+        String strText1 = OperandResolver.coerceValueToString(veText);
+        return OperandResolver.parseDouble(strText1);
+    }
+}
\ No newline at end of file
index 971aa26423f1b76a32742ddac25be88da9e43aa3..6de5ac10b6a2aa0b365685d68700829618cada97 100644 (file)
@@ -17,7 +17,6 @@
 
 package org.apache.poi.ss.formula.functions;
 
-import org.apache.commons.math3.distribution.TDistribution;
 import org.apache.poi.ss.formula.OperationEvaluationContext;
 import org.apache.poi.ss.formula.eval.*;
 
@@ -63,7 +62,7 @@ public final class TDistRt extends Fixed2ArgFunction implements FreeRefFunction
             if (degreesOfFreedom < 1) {
                 return ErrorEval.NUM_ERROR;
             }
-            return new NumberEval(TDist.tdistOneTail(Math.abs(number1), degreesOfFreedom));
+            return new NumberEval(TDist.tdistOneTail(number1, degreesOfFreedom));
         } catch (EvaluationException e) {
             return e.getErrorEval();
         }
index d0bca918aed0fea3f6ff1bb1bc64e61927873c6e..1037bc436dcd98b9982dae7f26dfe34605c5ccb4 100644 (file)
@@ -46,7 +46,7 @@ final class TestTDistRt {
         confirmValue("5.968191467", "8", 0.00016754180265310392);
         confirmValue("5.968191467", "8.2", 0.00016754180265310392);
         confirmValue("5.968191467", "8.9", 0.00016754180265310392);
-        confirmValue("-5.968191467", "8", 0.00016754180265310392);
+        confirmValue("-5.968191467", "8", 0.999832458, 0.01);
     }
 
     @Test
@@ -72,7 +72,7 @@ final class TestTDistRt {
             HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
             HSSFCell cell = wb.getSheetAt(0).getRow(0).createCell(100);
             assertDouble(fe, cell, "T.DIST.RT(A2,A3)", 0.027322465, 0.01);
-            assertDouble(fe, cell, "T.DIST.RT(-A2,A3)", 0.027322465, 0.01);
+            assertDouble(fe, cell, "T.DIST.RT(-A2,A3)", 0.972677535, 0.01);
         }
     }
 
@@ -82,9 +82,13 @@ final class TestTDistRt {
     }
 
     private static void confirmValue(String number1, String number2, double expected) {
+        confirmValue(number1, number2, expected, 0.0);
+    }
+
+    private static void confirmValue(String number1, String number2, double expected, double tolerance) {
         ValueEval result = invokeValue(number1, number2);
         assertEquals(NumberEval.class, result.getClass());
-        assertEquals(expected, ((NumberEval) result).getNumberValue(), 0.0);
+        assertEquals(expected, ((NumberEval) result).getNumberValue(), tolerance);
     }
 
     private static void confirmInvalidError(String number1, String number2) {