]> source.dussan.org Git - poi.git/commitdiff
[bug-62121] Fixed Power function of negative numbers. Thanks to Bob van den Berge...
authorPJ Fanning <fanningpj@apache.org>
Sun, 1 Apr 2018 15:52:13 +0000 (15:52 +0000)
committerPJ Fanning <fanningpj@apache.org>
Sun, 1 Apr 2018 15:52:13 +0000 (15:52 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1828143 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/ss/formula/eval/TwoOperandNumericOperation.java
src/testcases/org/apache/poi/ss/formula/eval/TestPowerEval.java [new file with mode: 0644]

index 60c3b31f57b5ae6caaf99ff48f6d6bbbfabef621..e5e13158323c1f67c6ab14c003d79ca50563d2d3 100644 (file)
@@ -106,6 +106,9 @@ public abstract class TwoOperandNumericOperation extends Fixed2ArgFunction imple
        };
        public static final Function PowerEval = new TwoOperandNumericOperation() {
                protected double evaluate(double d0, double d1) {
+                       if(d0 < 0 && Math.abs(d1) > 0.0 && Math.abs(d1) < 1.0) {
+                               return -1 * Math.pow(d0 * -1, d1);
+                       }
                        return Math.pow(d0, d1);
                }
        };
diff --git a/src/testcases/org/apache/poi/ss/formula/eval/TestPowerEval.java b/src/testcases/org/apache/poi/ss/formula/eval/TestPowerEval.java
new file mode 100644 (file)
index 0000000..eb7e367
--- /dev/null
@@ -0,0 +1,98 @@
+/* ====================================================================
+   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.eval;
+
+import junit.framework.TestCase;
+import org.apache.poi.hssf.usermodel.HSSFCell;
+import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
+import org.apache.poi.hssf.usermodel.HSSFRow;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.formula.functions.Function;
+import org.apache.poi.ss.usermodel.CellType;
+import org.apache.poi.ss.usermodel.CellValue;
+
+/**
+ * Tests for power operator evaluator.
+ *
+ * @author Bob van den Berge
+ */
+public final class TestPowerEval extends TestCase {
+
+    public void testPositiveValues() {
+        confirm(0, 0, 1);
+        confirm(1, 1, 0);
+        confirm(9, 3, 2);
+    }
+
+    public void testNegativeValues() {
+        confirm(-1, -1, 1);
+        confirm(1, 1, -1);
+        confirm(1, -10, 0);
+        confirm((1.0/3), 3, -1);
+    }
+
+    public void testPositiveDecimalValues() {
+        confirm(3, 27, (1/3.0));
+    }
+
+    public void testNegativeDecimalValues() {
+        confirm(-3, -27, (1/3.0));
+    }
+
+    public void testErrorValues() {
+        confirmError(-1.00001, 1.1);
+    }
+
+    public void testInSpreadSheet() {
+        HSSFWorkbook wb = new HSSFWorkbook();
+        HSSFSheet sheet = wb.createSheet("Sheet1");
+        HSSFRow row = sheet.createRow(0);
+        HSSFCell cell = row.createCell(0);
+        cell.setCellFormula("B1^C1");
+        row.createCell(1).setCellValue(-27);
+        row.createCell(2).setCellValue((1/3.0));
+
+        HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
+        CellValue cv = fe.evaluate(cell);
+
+        assertEquals(CellType.NUMERIC, cv.getCellType());
+        assertEquals(-3.0, cv.getNumberValue());
+    }
+
+    private void confirm(double expected, double a, double b) {
+        NumberEval result = (NumberEval) evaluate(EvalInstances.Power, a, b);
+
+        assertEquals(expected, result.getNumberValue());
+    }
+
+    private void confirmError(double a, double b) {
+        ErrorEval result = (ErrorEval) evaluate(EvalInstances.Power, a, b);
+
+        assertEquals("#NUM!", result.getErrorString());
+    }
+
+    private static ValueEval evaluate(Function instance, double... dArgs) {
+        ValueEval[] evalArgs;
+        evalArgs = new ValueEval[dArgs.length];
+        for (int i = 0; i < evalArgs.length; i++) {
+            evalArgs[i] = new NumberEval(dArgs[i]);
+        }
+        return instance.evaluate(evalArgs, -1, (short) -1);
+    }
+}