diff --git a/ClosedXML/Excel/CalcEngine/Functions/MathTrig.cs b/ClosedXML/Excel/CalcEngine/Functions/MathTrig.cs index cc56c25..aa1ff5b 100644 --- a/ClosedXML/Excel/CalcEngine/Functions/MathTrig.cs +++ b/ClosedXML/Excel/CalcEngine/Functions/MathTrig.cs @@ -17,6 +17,7 @@ ce.RegisterFunction("ABS", 1, Abs); ce.RegisterFunction("ACOS", 1, Acos); ce.RegisterFunction("ACOSH", 1, Acosh); + ce.RegisterFunction("ACOT", 1, Acot); ce.RegisterFunction("ASIN", 1, Asin); ce.RegisterFunction("ASINH", 1, Asinh); ce.RegisterFunction("ATAN", 1, Atan); @@ -483,6 +484,18 @@ return XLMath.ACosh(p[0]); } + private static object Acot(List p) + { + double x = Math.Atan(1.0 / p[0]); + + // Acot in Excel calculates the modulus of the function above. + // as the % operator is not the modulus, but the remainder, we have to calculate the modulus by hand: + while (x < 0) + x = x + Math.PI; + + return x; + } + private static object Asinh(List p) { return XLMath.ASinh(p[0]); diff --git a/ClosedXML_Tests/Excel/CalcEngine/MathTrigTests.cs b/ClosedXML_Tests/Excel/CalcEngine/MathTrigTests.cs index dcb6719..ec28464 100644 --- a/ClosedXML_Tests/Excel/CalcEngine/MathTrigTests.cs +++ b/ClosedXML_Tests/Excel/CalcEngine/MathTrigTests.cs @@ -12,6 +12,33 @@ { private readonly double tolerance = 1e-10; + [TestCase(-10, 3.041924001)] + [TestCase(-9, 3.030935432)] + [TestCase(-8, 3.017237659)] + [TestCase(-7, 2.999695599)] + [TestCase(-6, 2.976443976)] + [TestCase(-5, 2.944197094)] + [TestCase(-4, 2.89661399)] + [TestCase(-3, 2.819842099)] + [TestCase(-2, 2.677945045)] + [TestCase(-1, 2.35619449)] + [TestCase(0, 1.570796327)] + [TestCase(1, 0.785398163)] + [TestCase(2, 0.463647609)] + [TestCase(3, 0.321750554)] + [TestCase(4, 0.244978663)] + [TestCase(5, 0.19739556)] + [TestCase(6, 0.165148677)] + [TestCase(7, 0.141897055)] + [TestCase(8, 0.124354995)] + [TestCase(9, 0.110657221)] + [TestCase(10, 0.099668652)] + public void Acot_ReturnsCorrectValue(double input, double expectedResult) + { + var actual = (double)XLWorkbook.EvaluateExpr(string.Format(@"ACOT({0})", input.ToString(CultureInfo.InvariantCulture))); + Assert.AreEqual(expectedResult, actual, tolerance * 10); + } + [TestCase(4, 3, 20)] [TestCase(10, 3, 220)] [TestCase(0, 0, 1)]