Skip to content

Commit

Permalink
Merge pull request #406 from igitur/issue347-floor-function-parameters
Browse files Browse the repository at this point in the history
Fully implement FLOOR function
  • Loading branch information
igitur committed Aug 23, 2017
2 parents 446c41f + 405eb41 commit f2ce415
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 26 deletions.
4 changes: 2 additions & 2 deletions ClosedXML/Excel/CalcEngine/CalcEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -413,11 +413,11 @@ private Expression ParseAtom()
var pCnt = p == null ? 0 : p.Count;
if (fnDef.ParmMin != -1 && pCnt < fnDef.ParmMin)
{
Throw("Too few parameters.");
Throw(string.Format("Too few parameters for function '{0}'. Expected a minimum of {1} and a maximum of {2}.", id, fnDef.ParmMin, fnDef.ParmMax));
}
if (fnDef.ParmMax != -1 && pCnt > fnDef.ParmMax)
{
Throw("Too many parameters.");
Throw(string.Format("Too many parameters for function '{0}'.Expected a minimum of {1} and a maximum of {2}.", id, fnDef.ParmMin, fnDef.ParmMax));
}
x = new FunctionExpression(fnDef, p);
break;
Expand Down
71 changes: 47 additions & 24 deletions ClosedXML/Excel/CalcEngine/Functions/MathTrig.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using ClosedXML.Excel.CalcEngine.Functions;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using ClosedXML.Excel.CalcEngine.Functions;

namespace ClosedXML.Excel.CalcEngine
{
Expand All @@ -29,7 +29,8 @@ public static void Register(CalcEngine ce)
ce.RegisterFunction("EXP", 1, Exp);
ce.RegisterFunction("FACT", 1, Fact);
ce.RegisterFunction("FACTDOUBLE", 1, FactDouble);
ce.RegisterFunction("FLOOR", 1, Floor);
ce.RegisterFunction("FLOOR", 1, 2, Floor);
//ce.RegisterFunction("FLOOR.MATH", 1, 3, FloorMath);
ce.RegisterFunction("GCD", 1, 255, Gcd);
ce.RegisterFunction("INT", 1, Int);
ce.RegisterFunction("LCM", 1, 255, Lcm);
Expand Down Expand Up @@ -120,12 +121,27 @@ private static object Exp(List<Expression> p)

private static object Floor(List<Expression> p)
{
return Math.Floor(p[0]);
double number = p[0];
double significance = 1;
if (p.Count > 1)
significance = p[1];

if (significance < 0)
{
number = -number;
significance = -significance;

return -Math.Floor(number / significance) * significance;
}
else if (significance == 1)
return Math.Floor(number);
else
return Math.Floor(number / significance) * significance;
}

private static object Int(List<Expression> p)
{
return (int) ((double) p[0]);
return (int)((double)p[0]);
}

private static object Ln(List<Expression> p)
Expand All @@ -135,7 +151,7 @@ private static object Ln(List<Expression> p)

private static object Log(List<Expression> p)
{
var lbase = p.Count > 1 ? (double) p[1] : 10;
var lbase = p.Count > 1 ? (double)p[1] : 10;
return Math.Log(p[0], lbase);
}

Expand All @@ -161,7 +177,7 @@ private static object Rand(List<Expression> p)

private static object RandBetween(List<Expression> p)
{
return _rnd.Next((int) (double) p[0], (int) (double) p[1]);
return _rnd.Next((int)(double)p[0], (int)(double)p[1]);
}

private static object Sign(List<Expression> p)
Expand Down Expand Up @@ -240,42 +256,42 @@ private static object Tanh(List<Expression> p)

private static object Trunc(List<Expression> p)
{
return (double) (int) ((double) p[0]);
return (double)(int)((double)p[0]);
}

public static double DegreesToRadians(double degrees)
{
return (Math.PI/180.0)*degrees;
return (Math.PI / 180.0) * degrees;
}

public static double RadiansToDegrees(double radians)
{
return (180.0/Math.PI)*radians;
return (180.0 / Math.PI) * radians;
}

public static double GradsToRadians(double grads)
{
return (grads/200.0)*Math.PI;
return (grads / 200.0) * Math.PI;
}

public static double RadiansToGrads(double radians)
{
return (radians/Math.PI)*200.0;
return (radians / Math.PI) * 200.0;
}

public static double DegreesToGrads(double degrees)
{
return (degrees/9.0)*10.0;
return (degrees / 9.0) * 10.0;
}

public static double GradsToDegrees(double grads)
{
return (grads/10.0)*9.0;
return (grads / 10.0) * 9.0;
}

public static double ASinh(double x)
{
return (Math.Log(x + Math.Sqrt(x*x + 1.0)));
return (Math.Log(x + Math.Sqrt(x * x + 1.0)));
}

private static object Acosh(List<Expression> p)
Expand All @@ -295,8 +311,8 @@ private static object Atanh(List<Expression> p)

private static object Combin(List<Expression> p)
{
Int32 n = (int) p[0];
Int32 k = (int) p[1];
Int32 n = (int)p[0];
Int32 k = (int)p[1];
return XLMath.Combin(n, k);
}

Expand All @@ -305,8 +321,6 @@ private static object Degrees(List<Expression> p)
return p[0] * (180.0 / Math.PI);
}



private static object Fact(List<Expression> p)
{
var num = Math.Floor(p[0]);
Expand Down Expand Up @@ -348,7 +362,7 @@ private static object Lcm(List<Expression> p)
private static int Lcm(int a, int b)
{
if (a == 0 || b == 0) return 0;
return a * ( b / Gcd(a, b));
return a * (b / Gcd(a, b));
}

private static object Mod(List<Expression> p)
Expand Down Expand Up @@ -479,7 +493,6 @@ private static object Round(List<Expression> p)
temp = Math.Round(temp, 0, MidpointRounding.AwayFromZero);
return temp * Math.Pow(10, digits);
}

}

private static object RoundDown(List<Expression> p)
Expand Down Expand Up @@ -512,7 +525,7 @@ private static object SeriesSum(List<Expression> p)
var obj = p[3] as XObjectExpression;

if (obj == null)
return p[3] * Math.Pow(x , n);
return p[3] * Math.Pow(x, n);

Double total = 0;
Int32 i = 0;
Expand Down Expand Up @@ -540,26 +553,37 @@ private static object Subtotal(List<Expression> p)
{
case 1:
return tally.Average();

case 2:
return tally.Count(true);

case 3:
return tally.Count(false);

case 4:
return tally.Max();

case 5:
return tally.Min();

case 6:
return tally.Product();

case 7:
return tally.Std();

case 8:
return tally.StdP();

case 9:
return tally.Sum();

case 10:
return tally.Var();

case 11:
return tally.VarP();

default:
throw new ArgumentException("Function not supported.");
}
Expand Down Expand Up @@ -591,19 +615,18 @@ private static object MMult(List<Expression> p)
}
}


return C;
}

private static double[,] GetArray(Expression expression)
{
var oExp1 = expression as XObjectExpression;
if (oExp1 == null) return new [,]{{(Double)expression}};
if (oExp1 == null) return new[,] { { (Double)expression } };

var range = (oExp1.Value as CellRangeReference).Range;
var rowCount = range.RowCount();
var columnCount = range.ColumnCount();
var arr = new double[rowCount,columnCount];
var arr = new double[rowCount, columnCount];

for (int row = 0; row < rowCount; row++)
{
Expand Down
1 change: 1 addition & 0 deletions ClosedXML_Tests/ClosedXML_Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
<Compile Include="Excel\CalcEngine\InformationTests.cs" />
<Compile Include="Excel\CalcEngine\LogicalTests.cs" />
<Compile Include="Excel\CalcEngine\LookupTests.cs" />
<Compile Include="Excel\CalcEngine\MathTrigTests.cs" />
<Compile Include="Excel\CalcEngine\StatisticalTests.cs" />
<Compile Include="Excel\CalcEngine\TextTests.cs" />
<Compile Include="Excel\Comments\CommentsTests.cs" />
Expand Down
65 changes: 65 additions & 0 deletions ClosedXML_Tests/Excel/CalcEngine/MathTrigTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using ClosedXML.Excel;
using NUnit.Framework;
using System;

namespace ClosedXML_Tests.Excel.CalcEngine
{
[TestFixture]
public class MathTrigTests
{
[Test]
public void Floor()
{
Object actual;

actual = XLWorkbook.EvaluateExpr(@"FLOOR(1.2)");
Assert.AreEqual(1, actual);

actual = XLWorkbook.EvaluateExpr(@"FLOOR(1.7)");
Assert.AreEqual(1, actual);

actual = XLWorkbook.EvaluateExpr(@"FLOOR(-1.7)");
Assert.AreEqual(-2, actual);

actual = XLWorkbook.EvaluateExpr(@"FLOOR(1.2, 1)");
Assert.AreEqual(1, actual);

actual = XLWorkbook.EvaluateExpr(@"FLOOR(1.7, 1)");
Assert.AreEqual(1, actual);

actual = XLWorkbook.EvaluateExpr(@"FLOOR(-1.7, 1)");
Assert.AreEqual(-2, actual);

actual = XLWorkbook.EvaluateExpr(@"FLOOR(0.4, 2)");
Assert.AreEqual(0, actual);

actual = XLWorkbook.EvaluateExpr(@"FLOOR(2.7, 2)");
Assert.AreEqual(2, actual);

actual = XLWorkbook.EvaluateExpr(@"FLOOR(7.8, 2)");
Assert.AreEqual(6, actual);

actual = XLWorkbook.EvaluateExpr(@"FLOOR(-5.5, -2)");
Assert.AreEqual(-4, actual);
}

//[Test]
// Functions have to support a period first before we can implement this
public void FloorMath()
{
Object actual;

actual = XLWorkbook.EvaluateExpr(@"FLOOR.MATH(24.3, 5)");
Assert.AreEqual(20, actual);

actual = XLWorkbook.EvaluateExpr(@"FLOOR.MATH(6.7)");
Assert.AreEqual(6, actual);

actual = XLWorkbook.EvaluateExpr(@"FLOOR.MATH(-8.1, 2)");
Assert.AreEqual(-10, actual);

actual = XLWorkbook.EvaluateExpr(@"FLOOR.MATH(-5.5, 2, -1)");
Assert.AreEqual(-4, actual);
}
}
}

0 comments on commit f2ce415

Please sign in to comment.