]> source.dussan.org Git - poi.git/commitdiff
support gcd function
authorPJ Fanning <fanningpj@apache.org>
Fri, 29 Apr 2022 22:44:57 +0000 (22:44 +0000)
committerPJ Fanning <fanningpj@apache.org>
Fri, 29 Apr 2022 22:44:57 +0000 (22:44 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1900408 13f79535-47bb-0310-9956-ffa450edef68

poi/src/main/java/org/apache/poi/ss/formula/functions/Gcd.java
poi/src/test/java/org/apache/poi/ss/formula/functions/TestGcd.java

index 6da25ed279dc8acd4a01524d0931a10388c3e8fc..6b6f051607edf4ab704b779149445125a2ebd75c 100644 (file)
@@ -30,6 +30,8 @@ public class Gcd implements FreeRefFunction {
 
     public static final Gcd instance = new Gcd();
 
+    private static final long MAX_INPUT = (long)Math.pow(2, 53);
+
     @Override
     public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) {
         if (args.length < 1) {
@@ -37,11 +39,11 @@ public class Gcd implements FreeRefFunction {
         } else if (args.length == 1) {
             try {
                 ValueEval v1 = OperandResolver.getSingleValue(args[0], ec.getRowIndex(), ec.getColumnIndex());
-                long l = (long)OperandResolver.coerceValueToDouble(v1);
-                if (l < 0) {
+                double d = OperandResolver.coerceValueToDouble(v1);
+                if (isInvalidInput(d)) {
                     return ErrorEval.NUM_ERROR;
                 }
-                return new NumberEval(l);
+                return new NumberEval((long)d);
             } catch (EvaluationException ee) {
                 return ErrorEval.VALUE_INVALID;
             }
@@ -50,11 +52,11 @@ public class Gcd implements FreeRefFunction {
                 ArrayList<Long> evals = new ArrayList<>();
                 for (int i = 0; i < args.length; i++) {
                     ValueEval ve = OperandResolver.getSingleValue(args[i], ec.getRowIndex(), ec.getColumnIndex());
-                    long l = (long)OperandResolver.coerceValueToDouble(ve);
-                    if (l < 0) {
+                    double d = OperandResolver.coerceValueToDouble(ve);
+                    if (isInvalidInput(d)) {
                         return ErrorEval.NUM_ERROR;
                     }
-                    evals.add(l);
+                    evals.add((long)d);
                 }
                 long result = evals.get(0);
                 for (int i = 1; i < evals.size(); i++) {
@@ -66,4 +68,8 @@ public class Gcd implements FreeRefFunction {
             }
         }
     }
+
+    private boolean isInvalidInput(double d) {
+        return (d < 0 || d > MAX_INPUT);
+    }
 }
index f476197d77dd32382b4b36a60a83702f61d20516..a4ddb8d2b2a8318f2d617df2ede830f9c9951f9d 100644 (file)
@@ -54,12 +54,14 @@ final class TestGcd {
         confirmValue(Arrays.asList(5, 0), 5.0);
         confirmValue(Arrays.asList(10, 5, 0), 5.0);
         confirmValue(Arrays.asList(10.9, 5, 0), 5.0);
+        confirmValue(Arrays.asList(Math.pow(2, 53), 2.0), 2.0);
     }
 
     @Test
     void testNumError() {
         confirmNumError(Arrays.asList(-1));
         confirmNumError(Arrays.asList(10, -1));
+        confirmNumError(Arrays.asList(Math.pow(2, 54), 2.0));
     }
 
     @Test