diff --git a/ClosedXML/Excel/CalcEngine/Functions/MathTrig.cs b/ClosedXML/Excel/CalcEngine/Functions/MathTrig.cs index 5a25661..9963e3c 100644 --- a/ClosedXML/Excel/CalcEngine/Functions/MathTrig.cs +++ b/ClosedXML/Excel/CalcEngine/Functions/MathTrig.cs @@ -367,10 +367,10 @@ private static object Mod(List p) { - Int32 n = (int)Math.Abs(p[0]); - Int32 d = (int)p[1]; - var ret = n % d; - return d < 0 ? ret * -1 : ret; + double number = p[0]; + double divisor = p[1]; + + return number - Math.Floor(number / divisor) * divisor; } private static object MRound(List p) diff --git a/ClosedXML_Tests/Excel/CalcEngine/MathTrigTests.cs b/ClosedXML_Tests/Excel/CalcEngine/MathTrigTests.cs index 6d30f1f..2a64f05 100644 --- a/ClosedXML_Tests/Excel/CalcEngine/MathTrigTests.cs +++ b/ClosedXML_Tests/Excel/CalcEngine/MathTrigTests.cs @@ -7,6 +7,8 @@ [TestFixture] public class MathTrigTests { + private readonly double tolerance = 1e-10; + [Test] public void Floor() { @@ -61,5 +63,40 @@ actual = XLWorkbook.EvaluateExpr(@"FLOOR.MATH(-5.5, 2, -1)"); Assert.AreEqual(-4, actual); } + + [Test] + public void Mod() + { + double actual; + + actual = (double)XLWorkbook.EvaluateExpr(@"MOD(1.5, 1)"); + Assert.AreEqual(0.5, actual, tolerance); + + actual = (double)XLWorkbook.EvaluateExpr(@"MOD(3, 2)"); + Assert.AreEqual(1, actual, tolerance); + + actual = (double)XLWorkbook.EvaluateExpr(@"MOD(-3, 2)"); + Assert.AreEqual(1, actual, tolerance); + + actual = (double)XLWorkbook.EvaluateExpr(@"MOD(3, -2)"); + Assert.AreEqual(-1, actual, tolerance); + + actual = (double)XLWorkbook.EvaluateExpr(@"MOD(-3, -2)"); + Assert.AreEqual(-1, actual, tolerance); + + ////// + + actual = (double)XLWorkbook.EvaluateExpr(@"MOD(-4.3, -0.5)"); + Assert.AreEqual(-0.3, actual, tolerance); + + actual = (double)XLWorkbook.EvaluateExpr(@"MOD(6.9, -0.2)"); + Assert.AreEqual(-0.1, actual, tolerance); + + actual = (double)XLWorkbook.EvaluateExpr(@"MOD(0.7, 0.6)"); + Assert.AreEqual(0.1, actual, tolerance); + + actual = (double)XLWorkbook.EvaluateExpr(@"MOD(6.2, 1.1)"); + Assert.AreEqual(0.7, actual, tolerance); + } } }