diff --git a/ClosedXML/ClosedXML/ClosedXML/ClosedXML.csproj b/ClosedXML/ClosedXML/ClosedXML/ClosedXML.csproj
index 6a45326..5f7d00c 100644
--- a/ClosedXML/ClosedXML/ClosedXML/ClosedXML.csproj
+++ b/ClosedXML/ClosedXML/ClosedXML/ClosedXML.csproj
@@ -149,6 +149,7 @@
+
diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/Functions/MathTrig.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/Functions/MathTrig.cs
index 0e8b804..92b8289 100644
--- a/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/Functions/MathTrig.cs
+++ b/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/Functions/MathTrig.cs
@@ -4,26 +4,29 @@
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
+using ClosedXML.Excel.CalcEngine.Functions;
namespace ClosedXML.Excel.CalcEngine
{
- static class MathTrig
+ internal static class MathTrig
{
+ private static readonly Random _rnd = new Random();
+
public static void Register(CalcEngine ce)
{
ce.RegisterFunction("ABS", 1, Abs);
ce.RegisterFunction("ACOS", 1, Acos);
- //ce.RegisterFunction("ACOSH", Acosh, 1);
+ ce.RegisterFunction("ACOSH", 1, Acosh);
ce.RegisterFunction("ASIN", 1, Asin);
- //ce.RegisterFunction("ASINH", Asinh, 1);
+ ce.RegisterFunction("ASINH", 1, Asinh);
ce.RegisterFunction("ATAN", 1, Atan);
ce.RegisterFunction("ATAN2", 2, Atan2);
- //ce.RegisterFunction("ATANH", Atanh, 1);
+ ce.RegisterFunction("ATANH", 1, Atanh);
ce.RegisterFunction("CEILING", 1, Ceiling);
- //ce.RegisterFunction("COMBIN", Combin, 1);
+ ce.RegisterFunction("COMBIN", 2, Combin);
ce.RegisterFunction("COS", 1, Cos);
ce.RegisterFunction("COSH", 1, Cosh);
- //ce.RegisterFunction("DEGREES", Degrees, 1);
+ ce.RegisterFunction("DEGREES", 1, Degrees);
//ce.RegisterFunction("EVEN", Even, 1);
ce.RegisterFunction("EXP", 1, Exp);
//ce.RegisterFunction("FACT", Fact, 1);
@@ -71,110 +74,133 @@
ce.RegisterFunction("TANH", 1, Tanh);
ce.RegisterFunction("TRUNC", 1, Trunc);
}
- static object Abs(List p)
+
+ private static object Abs(List p)
{
- return Math.Abs((double)p[0]);
+ return Math.Abs(p[0]);
}
- static object Acos(List p)
+
+ private static object Acos(List p)
{
- return Math.Acos((double)p[0]);
+ return Math.Acos(p[0]);
}
- static object Asin(List p)
+
+ private static object Asin(List p)
{
- return Math.Asin((double)p[0]);
+ return Math.Asin(p[0]);
}
- static object Atan(List p)
+
+ private static object Atan(List p)
{
- return Math.Atan((double)p[0]);
+ return Math.Atan(p[0]);
}
- static object Atan2(List p)
+
+ private static object Atan2(List p)
{
- return Math.Atan2((double)p[0], (double)p[1]);
+ return Math.Atan2(p[0], p[1]);
}
- static object Ceiling(List p)
+
+ private static object Ceiling(List p)
{
- return Math.Ceiling((double)p[0]);
+ return Math.Ceiling(p[0]);
}
- static object Cos(List p)
+
+ private static object Cos(List p)
{
- return Math.Cos((double)p[0]);
+ return Math.Cos(p[0]);
}
- static object Cosh(List p)
+
+ private static object Cosh(List p)
{
- return Math.Cosh((double)p[0]);
+ return Math.Cosh(p[0]);
}
- static object Exp(List p)
+
+ private static object Exp(List p)
{
- return Math.Exp((double)p[0]);
+ return Math.Exp(p[0]);
}
- static object Floor(List p)
+
+ private static object Floor(List p)
{
- return Math.Floor((double)p[0]);
+ return Math.Floor(p[0]);
}
- static object Int(List p)
+
+ private static object Int(List p)
{
- return (int)((double)p[0]);
+ return (int) ((double) p[0]);
}
- static object Ln(List p)
+
+ private static object Ln(List p)
{
- return Math.Log((double)p[0]);
+ return Math.Log(p[0]);
}
- static object Log(List p)
+
+ private static object Log(List p)
{
- var lbase = p.Count > 1 ? (double)p[1] : 10;
- return Math.Log((double)p[0], lbase);
+ var lbase = p.Count > 1 ? (double) p[1] : 10;
+ return Math.Log(p[0], lbase);
}
- static object Log10(List p)
+
+ private static object Log10(List p)
{
- return Math.Log10((double)p[0]);
+ return Math.Log10(p[0]);
}
- static object Pi(List p)
+
+ private static object Pi(List p)
{
return Math.PI;
}
- static object Power(List p)
+
+ private static object Power(List p)
{
- return Math.Pow((double)p[0], (double)p[1]);
+ return Math.Pow(p[0], p[1]);
}
- static Random _rnd = new Random();
- static object Rand(List p)
+
+ private static object Rand(List p)
{
return _rnd.NextDouble();
}
- static object RandBetween(List p)
+
+ private static object RandBetween(List p)
{
- return _rnd.Next((int)(double)p[0], (int)(double)p[1]);
+ return _rnd.Next((int) (double) p[0], (int) (double) p[1]);
}
- static object Sign(List p)
+
+ private static object Sign(List p)
{
- return Math.Sign((double)p[0]);
+ return Math.Sign(p[0]);
}
- static object Sin(List p)
+
+ private static object Sin(List p)
{
- return Math.Sin((double)p[0]);
+ return Math.Sin(p[0]);
}
- static object Sinh(List p)
+
+ private static object Sinh(List p)
{
- return Math.Sinh((double)p[0]);
+ return Math.Sinh(p[0]);
}
- static object Sqrt(List p)
+
+ private static object Sqrt(List p)
{
- return Math.Sqrt((double)p[0]);
+ return Math.Sqrt(p[0]);
}
- static object Sum(List p)
+
+ private static object Sum(List p)
{
var tally = new Tally();
- foreach (Expression e in p)
+ foreach (var e in p)
{
tally.Add(e);
}
return tally.Sum();
}
- static object SumIf(List p)
+
+ private static object SumIf(List p)
{
// get parameters
- IEnumerable range = p[0] as IEnumerable;
- IEnumerable sumRange = p.Count < 3 ? range : p[2] as IEnumerable;
+ var range = p[0] as IEnumerable;
+ var sumRange = p.Count < 3 ? range : p[2] as IEnumerable;
var criteria = p[1].Evaluate();
// build list of values in range and sumRange
@@ -192,7 +218,7 @@
// compute total
var ce = new CalcEngine();
var tally = new Tally();
- for (int i = 0; i < Math.Min(rangeValues.Count, sumRangeValues.Count); i++)
+ for (var i = 0; i < Math.Min(rangeValues.Count, sumRangeValues.Count); i++)
{
if (ValueSatisfiesCriteria(rangeValues[i], criteria, ce))
{
@@ -203,7 +229,8 @@
// done
return tally.Sum();
}
- static bool ValueSatisfiesCriteria(object value, object criteria, CalcEngine ce)
+
+ private static bool ValueSatisfiesCriteria(object value, object criteria, CalcEngine ce)
{
// safety...
if (value == null)
@@ -214,7 +241,7 @@
// if criteria is a number, straight comparison
if (criteria is double)
{
- return (double)value == (double)criteria;
+ return (double) value == (double) criteria;
}
// convert criteria to string
@@ -237,14 +264,14 @@
!double.TryParse(m.Groups[3].Value, out d))
{
expression = string.Format("\"{0}\"{1}\"{2}\"",
- m.Groups[1].Value,
- m.Groups[2].Value,
- m.Groups[3].Value);
+ m.Groups[1].Value,
+ m.Groups[2].Value,
+ m.Groups[3].Value);
}
}
// evaluate
- return (bool)ce.Evaluate(expression);
+ return (bool) ce.Evaluate(expression);
}
// if criteria is a regular expression, use regex
@@ -261,20 +288,85 @@
}
// should never get here?
- System.Diagnostics.Debug.Assert(false, "failed to evaluate criteria in SumIf");
+ Debug.Assert(false, "failed to evaluate criteria in SumIf");
return false;
}
- static object Tan(List p)
+
+ private static object Tan(List p)
{
- return Math.Tan((double)p[0]);
+ return Math.Tan(p[0]);
}
- static object Tanh(List p)
+
+ private static object Tanh(List p)
{
- return Math.Tanh((double)p[0]);
+ return Math.Tanh(p[0]);
}
- static object Trunc(List p)
+
+ private static object Trunc(List 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;
+ }
+
+ public static double RadiansToDegrees(double radians)
+ {
+ return (180.0/Math.PI)*radians;
+ }
+
+ public static double GradsToRadians(double grads)
+ {
+ return (grads/200.0)*Math.PI;
+ }
+
+ public static double RadiansToGrads(double radians)
+ {
+ return (radians/Math.PI)*200.0;
+ }
+
+ public static double DegreesToGrads(double degrees)
+ {
+ return (degrees/9.0)*10.0;
+ }
+
+ public static double GradsToDegrees(double grads)
+ {
+ return (grads/10.0)*9.0;
+ }
+
+ public static double ASinh(double x)
+ {
+ return (Math.Log(x + Math.Sqrt(x*x + 1.0)));
+ }
+
+ private static object Acosh(List p)
+ {
+ return XLMath.ACosh(p[0]);
+ }
+
+ private static object Asinh(List p)
+ {
+ return XLMath.ASinh(p[0]);
+ }
+
+ private static object Atanh(List p)
+ {
+ return XLMath.ATanh(p[0]);
+ }
+
+ private static object Combin(List p)
+ {
+ Int32 n = (int) p[0];
+ Int32 k = (int) p[1];
+ return XLMath.Combin(n, k);
+ }
+
+ private static object Degrees(List p)
+ {
+ return Math.PI * p[0] / 180.0;
}
}
-}
+}
\ No newline at end of file
diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/Functions/XLMath.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/Functions/XLMath.cs
new file mode 100644
index 0000000..b328d28
--- /dev/null
+++ b/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/Functions/XLMath.cs
@@ -0,0 +1,92 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace ClosedXML.Excel.CalcEngine.Functions
+{
+ public static class XLMath
+ {
+ public static double DegreesToRadians(double degrees)
+ {
+ return (Math.PI / 180.0) * degrees;
+ }
+
+ public static double RadiansToDegrees(double radians)
+ {
+ return (180.0 / Math.PI) * radians;
+ }
+
+ public static double GradsToRadians(double grads)
+ {
+ return (grads / 200.0) * Math.PI;
+ }
+
+ public static double RadiansToGrads(double radians)
+ {
+ return (radians / Math.PI) * 200.0;
+ }
+
+ public static double DegreesToGrads(double degrees)
+ {
+ return (degrees / 9.0) * 10.0;
+ }
+
+ public static double GradsToDegrees(double grads)
+ {
+ return (grads / 10.0) * 9.0;
+ }
+
+ public static double ASinh(double x)
+ {
+ return (Math.Log(x + Math.Sqrt(x * x + 1.0)));
+ }
+
+ public static double ACosh(double x)
+ {
+ return (Math.Log(x + Math.Sqrt((x * x) - 1.0)));
+ }
+
+ public static double ATanh(double x)
+ {
+ return (Math.Log((1.0 + x) / (1.0 - x)) / 2.0);
+ }
+
+ public static double ACoth(double x)
+ {
+ //return (Math.Log((x + 1.0) / (x - 1.0)) / 2.0);
+ return (ATanh(1.0 / x));
+ }
+
+ public static double ASech(double x)
+ {
+ return (ACosh(1.0 / x));
+ }
+
+ public static double ACsch(double x)
+ {
+ return (ASinh(1.0 / x));
+ }
+
+ public static double Sech(double x)
+ {
+ return (1.0 / Math.Cosh(x));
+ }
+
+ public static double Csch(double x)
+ {
+ return (1.0 / Math.Sinh(x));
+ }
+
+ public static double Coth(double x)
+ {
+ return (Math.Cosh(x) / Math.Sinh(x));
+ }
+
+ public static double Combin(Int32 n, Int32 k)
+ {
+ if (k == 0) return 1;
+ return n * Combin(n - 1, k - 1) / k;
+ }
+ }
+}
diff --git a/ClosedXML/ClosedXML/ClosedXML_Net3.5/ClosedXML_Net3.5.csproj b/ClosedXML/ClosedXML/ClosedXML_Net3.5/ClosedXML_Net3.5.csproj
index 27d3fd3..d6e53d5 100644
--- a/ClosedXML/ClosedXML/ClosedXML_Net3.5/ClosedXML_Net3.5.csproj
+++ b/ClosedXML/ClosedXML/ClosedXML_Net3.5/ClosedXML_Net3.5.csproj
@@ -189,6 +189,9 @@
Excel\CalcEngine\Functions\Text.cs
+
+ Excel\CalcEngine\Functions\XLMath.cs
+
Excel\CalcEngine\Token.cs