From 9ced6d1712edf28e7169b287e4bca63a57261312 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Fri, 29 Apr 2022 22:44:57 +0000 Subject: [PATCH] support gcd function git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1900408 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/ss/formula/functions/Gcd.java | 18 ++++++++++++------ .../poi/ss/formula/functions/TestGcd.java | 2 ++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/poi/src/main/java/org/apache/poi/ss/formula/functions/Gcd.java b/poi/src/main/java/org/apache/poi/ss/formula/functions/Gcd.java index 6da25ed279..6b6f051607 100644 --- a/poi/src/main/java/org/apache/poi/ss/formula/functions/Gcd.java +++ b/poi/src/main/java/org/apache/poi/ss/formula/functions/Gcd.java @@ -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 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); + } } diff --git a/poi/src/test/java/org/apache/poi/ss/formula/functions/TestGcd.java b/poi/src/test/java/org/apache/poi/ss/formula/functions/TestGcd.java index f476197d77..a4ddb8d2b2 100644 --- a/poi/src/test/java/org/apache/poi/ss/formula/functions/TestGcd.java +++ b/poi/src/test/java/org/apache/poi/ss/formula/functions/TestGcd.java @@ -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