diff --git a/ClosedXML/Excel/CalcEngine/Functions/MathTrig.cs b/ClosedXML/Excel/CalcEngine/Functions/MathTrig.cs index f578f42..66fbd8c 100644 --- a/ClosedXML/Excel/CalcEngine/Functions/MathTrig.cs +++ b/ClosedXML/Excel/CalcEngine/Functions/MathTrig.cs @@ -672,8 +672,17 @@ private static object FactDouble(List p) { + var input = p[0].Evaluate(); + + if (!(input is long || input is int || input is byte || input is double || input is float)) + throw new CellValueException(); + var num = Math.Floor(p[0]); double fact = 1.0; + + if (num < -1) + throw new NumberException(); + if (num > 1) { var start = Math.Abs(num % 2) < XLHelper.Epsilon ? 2 : 1; diff --git a/ClosedXML_Tests/Excel/CalcEngine/MathTrigTests.cs b/ClosedXML_Tests/Excel/CalcEngine/MathTrigTests.cs index 72b10fe..b58b134 100644 --- a/ClosedXML_Tests/Excel/CalcEngine/MathTrigTests.cs +++ b/ClosedXML_Tests/Excel/CalcEngine/MathTrigTests.cs @@ -822,6 +822,47 @@ Assert.Throws(() => XLWorkbook.EvaluateExpr(string.Format(@"FACT(""x"")"))); } + [TestCase(0, 1L)] + [TestCase(1, 1L)] + [TestCase(2, 2L)] + [TestCase(3, 3L)] + [TestCase(4, 8L)] + [TestCase(5, 15L)] + [TestCase(6, 48L)] + [TestCase(7, 105L)] + [TestCase(8, 384L)] + [TestCase(9, 945L)] + [TestCase(10, 3840L)] + [TestCase(11, 10395L)] + [TestCase(12, 46080L)] + [TestCase(13, 135135L)] + [TestCase(14, 645120)] + [TestCase(15, 2027025)] + [TestCase(16, 10321920)] + [TestCase(-1, 1L)] + [TestCase(0, 1)] + [TestCase(0.1, 1L)] + [TestCase(1.4, 1L)] + [TestCase(2.3, 2L)] + [TestCase(2.8, 2L)] + public void FactDouble_ReturnsCorrectResult(double input, long expectedResult) + { + var actual = (double)XLWorkbook.EvaluateExpr(string.Format(@"FACTDOUBLE({0})", input.ToString(CultureInfo.InvariantCulture))); + Assert.AreEqual(expectedResult, actual); + } + + [Theory] + public void FactDouble_ThrowsNumberExceptionForInputSmallerThanMinus1([Range(-10, -2)] int input) + { + Assert.Throws(() => XLWorkbook.EvaluateExpr(string.Format(@"FACTDOUBLE({0})", input.ToString(CultureInfo.InvariantCulture)))); + } + + [Test] + public void FactDouble_ThrowsValueExceptionForNonNumericInput() + { + Assert.Throws(() => XLWorkbook.EvaluateExpr(string.Format(@"FACTDOUBLE(""x"")"))); + } + [Test] public void Floor() {