From 79317976ff5c0ded684d07883b67324a6127ecc0 Mon Sep 17 00:00:00 2001 From: Udo Klimaschewski Date: Sun, 7 Jul 2024 10:12:00 +0200 Subject: [PATCH] adds EvaluationException to acos and acosr functions for invalid parameter values (#489) --- .../evalex/functions/AbstractFunction.java | 3 ++ .../functions/trigonometric/AcosFunction.java | 20 +++++++++++-- .../trigonometric/AcosRFunction.java | 21 ++++++++++++-- .../functions/trigonometric/AsinFunction.java | 3 -- .../TrigonometricFunctionsTest.java | 28 +++++++++++++++++++ 5 files changed, 66 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/ezylang/evalex/functions/AbstractFunction.java b/src/main/java/com/ezylang/evalex/functions/AbstractFunction.java index a6b96d02..646defd9 100644 --- a/src/main/java/com/ezylang/evalex/functions/AbstractFunction.java +++ b/src/main/java/com/ezylang/evalex/functions/AbstractFunction.java @@ -15,6 +15,8 @@ */ package com.ezylang.evalex.functions; +import static java.math.BigDecimal.valueOf; + import com.ezylang.evalex.EvaluationException; import com.ezylang.evalex.data.EvaluationValue; import com.ezylang.evalex.parser.Token; @@ -28,6 +30,7 @@ */ public abstract class AbstractFunction implements FunctionIfc { + protected static final BigDecimal MINUS_ONE = valueOf(-1); private final List functionParameterDefinitions = new ArrayList<>(); private final boolean hasVarArgs; diff --git a/src/main/java/com/ezylang/evalex/functions/trigonometric/AcosFunction.java b/src/main/java/com/ezylang/evalex/functions/trigonometric/AcosFunction.java index 05926f5d..a89a97a6 100644 --- a/src/main/java/com/ezylang/evalex/functions/trigonometric/AcosFunction.java +++ b/src/main/java/com/ezylang/evalex/functions/trigonometric/AcosFunction.java @@ -15,20 +15,34 @@ */ package com.ezylang.evalex.functions.trigonometric; +import static java.math.BigDecimal.ONE; + +import com.ezylang.evalex.EvaluationException; import com.ezylang.evalex.Expression; import com.ezylang.evalex.data.EvaluationValue; import com.ezylang.evalex.functions.AbstractFunction; import com.ezylang.evalex.functions.FunctionParameter; import com.ezylang.evalex.parser.Token; +import java.math.BigDecimal; /** Returns the arc-cosine (in degrees). */ @FunctionParameter(name = "value") public class AcosFunction extends AbstractFunction { @Override public EvaluationValue evaluate( - Expression expression, Token functionToken, EvaluationValue... parameterValues) { + Expression expression, Token functionToken, EvaluationValue... parameterValues) + throws EvaluationException { + + BigDecimal parameterValue = parameterValues[0].getNumberValue(); - return expression.convertDoubleValue( - Math.toDegrees(Math.acos(parameterValues[0].getNumberValue().doubleValue()))); + if (parameterValue.compareTo(ONE) > 0) { + throw new EvaluationException( + functionToken, "Illegal acos(x) for x > 1: x = " + parameterValue); + } + if (parameterValue.compareTo(MINUS_ONE) < 0) { + throw new EvaluationException( + functionToken, "Illegal acos(x) for x < -1: x = " + parameterValue); + } + return expression.convertDoubleValue(Math.toDegrees(Math.acos(parameterValue.doubleValue()))); } } diff --git a/src/main/java/com/ezylang/evalex/functions/trigonometric/AcosRFunction.java b/src/main/java/com/ezylang/evalex/functions/trigonometric/AcosRFunction.java index 0951227d..1b57ca47 100644 --- a/src/main/java/com/ezylang/evalex/functions/trigonometric/AcosRFunction.java +++ b/src/main/java/com/ezylang/evalex/functions/trigonometric/AcosRFunction.java @@ -15,20 +15,35 @@ */ package com.ezylang.evalex.functions.trigonometric; +import static java.math.BigDecimal.ONE; + +import com.ezylang.evalex.EvaluationException; import com.ezylang.evalex.Expression; import com.ezylang.evalex.data.EvaluationValue; import com.ezylang.evalex.functions.AbstractFunction; import com.ezylang.evalex.functions.FunctionParameter; import com.ezylang.evalex.parser.Token; +import java.math.BigDecimal; /** Returns the arc-cosine (in radians). */ @FunctionParameter(name = "cosine") public class AcosRFunction extends AbstractFunction { @Override public EvaluationValue evaluate( - Expression expression, Token functionToken, EvaluationValue... parameterValues) { + Expression expression, Token functionToken, EvaluationValue... parameterValues) + throws EvaluationException { + + BigDecimal parameterValue = parameterValues[0].getNumberValue(); + + if (parameterValue.compareTo(ONE) > 0) { + throw new EvaluationException( + functionToken, "Illegal acosr(x) for x > 1: x = " + parameterValue); + } + if (parameterValue.compareTo(MINUS_ONE) < 0) { + throw new EvaluationException( + functionToken, "Illegal acosr(x) for x < -1: x = " + parameterValue); + } - return expression.convertDoubleValue( - Math.acos(parameterValues[0].getNumberValue().doubleValue())); + return expression.convertDoubleValue(Math.acos(parameterValue.doubleValue())); } } diff --git a/src/main/java/com/ezylang/evalex/functions/trigonometric/AsinFunction.java b/src/main/java/com/ezylang/evalex/functions/trigonometric/AsinFunction.java index c77cee82..bf47bbd9 100644 --- a/src/main/java/com/ezylang/evalex/functions/trigonometric/AsinFunction.java +++ b/src/main/java/com/ezylang/evalex/functions/trigonometric/AsinFunction.java @@ -16,7 +16,6 @@ package com.ezylang.evalex.functions.trigonometric; import static java.math.BigDecimal.ONE; -import static java.math.BigDecimal.valueOf; import com.ezylang.evalex.EvaluationException; import com.ezylang.evalex.Expression; @@ -30,8 +29,6 @@ @FunctionParameter(name = "value") public class AsinFunction extends AbstractFunction { - private static final BigDecimal MINUS_ONE = valueOf(-1); - @Override public EvaluationValue evaluate( Expression expression, Token functionToken, EvaluationValue... parameterValues) diff --git a/src/test/java/com/ezylang/evalex/functions/trigonometric/TrigonometricFunctionsTest.java b/src/test/java/com/ezylang/evalex/functions/trigonometric/TrigonometricFunctionsTest.java index 43355fa7..3a6a0413 100644 --- a/src/test/java/com/ezylang/evalex/functions/trigonometric/TrigonometricFunctionsTest.java +++ b/src/test/java/com/ezylang/evalex/functions/trigonometric/TrigonometricFunctionsTest.java @@ -41,6 +41,20 @@ void testAcos(String expression, String expectedResult) assertExpressionHasExpectedResult(expression, expectedResult); } + @Test + void testAcosThrowsExceptionPositive() { + assertThatThrownBy(() -> new Expression("ACOS(1.5)").evaluate()) + .isInstanceOf(EvaluationException.class) + .hasMessage("Illegal acos(x) for x > 1: x = 1.5"); + } + + @Test + void testAcosThrowsExceptionNegative() { + assertThatThrownBy(() -> new Expression("ACOS(-1.5)").evaluate()) + .isInstanceOf(EvaluationException.class) + .hasMessage("Illegal acos(x) for x < -1: x = -1.5"); + } + @ParameterizedTest @CsvSource( delimiter = ':', @@ -75,6 +89,20 @@ void testAcosR(String expression, String expectedResult) assertExpressionHasExpectedResult(expression, expectedResult); } + @Test + void testAcosRThrowsExceptionPositive() { + assertThatThrownBy(() -> new Expression("ACOSR(1.5)").evaluate()) + .isInstanceOf(EvaluationException.class) + .hasMessage("Illegal acosr(x) for x > 1: x = 1.5"); + } + + @Test + void testAcosRThrowsExceptionNegative() { + assertThatThrownBy(() -> new Expression("ACOSR(-1.5)").evaluate()) + .isInstanceOf(EvaluationException.class) + .hasMessage("Illegal acosr(x) for x < -1: x = -1.5"); + } + @ParameterizedTest @CsvSource( delimiter = ':',