So if you want to perform a complicated mathematical function (i.e. anything more
than addition or subtraction!) you’re better off using one of these functoids, or
an external assembly.
Once again, inline C# isn’t the fastest, but given a choice between a slow function
and no function, you might not have a choice.
For each functoid I’ve shown:
Functoids covered in this category:
Absolute Value | Modulo |
Addition | Multiplication |
Division | Round |
Integer | Square Root |
Maximum Value | Subtraction |
Minimum Value | Common Code |
Download the complete series as a single Microsoft
Word document (1.2MB) or Adobe
PDF document (620kb).
Mathematical Functoids |
||
|
|
|
Generates: C# |
Has XSLT Equivalent: in 2.0 only |
|
Emitted Code: public string MathAbs(string val) { string retval = “”; double d = 0; if (IsNumeric(val, ref d)) { double abs = Math.Abs(d); retval = abs.ToString(System.Globalization.CultureInfo.InvariantCulture); } return retval; } |
||
XSLT 1.0 Equivalent: (none) |
||
XSLT 2.0 Equivalent: abs(number) Note: In XSLT 1.0, you can achieve the desired result through use of an XSLT template and the xsl:when statement (i.e. check if number is < 0). |
||
|
|
|
Generates: C# |
Has XSLT Equivalent: in 1.0 and 2.0 |
|
Emitted Code: Note: there will be one overload per unique number of parameters. Here we show an example with two input parameters. public string MathAdd(string param0, string param1) { System.Collections.ArrayList listValues = new System.Collections.ArrayList(); listValues.Add(param0); listValues.Add(param1); double ret = 0; foreach (string obj in listValues) { double d = 0; if (IsNumeric(obj, ref d)) { ret += d; } else { return “”; } } return ret.ToString(System.Globalization.CultureInfo.InvariantCulture); } |
||
XSLT 1.0 Equivalent: Use the “+” operator e.g. ((number + number) |
||
XSLT 2.0 Equivalent: Use the “+” operator e.g. ((number + number) |
||
|
|
|
Generates: C# |
Has XSLT Equivalent: in 1.0 and 2.0 |
|
Emitted Code: Note: there will be one overload per unique number of parameters. Here we show an example with two input parameters. public string MathDivide(string val1, string val2) { string retval = “”; double d1 = 0; double d2 = 0; if (IsNumeric(val1, ref d1) && IsNumeric(val2, ref d2)) { if (d2 != 0) { double ret = d1 / d2; retval = ret.ToString(System.Globalization.CultureInfo.InvariantCulture); } } return retval; } |
||
XSLT 1.0 Equivalent: Use the div operator e.g. number div number |
||
XSLT 2.0 Equivalent: Use the div operator e.g. number div number |
||
|
|
|
Generates: C# |
Has XSLT Equivalent: No |
|
Emitted Code: public string MathInt(string val) { string retval = “”; double d = 0; if (IsNumeric(val, ref d)) { try { int i = Convert.ToInt32(d, System.Globalization.CultureInfo.InvariantCulture); if (i > d) { i = i – 1; } retval = i.ToString(System.Globalization.CultureInfo.InvariantCulture); } catch (Exception) { } } return retval; } |
||
XSLT 1.0 Equivalent: (none) |
||
XSLT 2.0 Equivalent: (none) Note: the floor() function will give an equivalent result e.g. floor(3.90) will give ‘3’. |
||
|
|
|
Generates: C# |
Has XSLT Equivalent: in 2.0 only |
|
Emitted Code: public string MathMax(string param0, string param1) { double max = Double.NegativeInfinity; System.Collections.ArrayList listValues = new System.Collections.ArrayList(); listValues.Add(param0); listValues.Add(param1); foreach (string obj in listValues) { double d = 0; if (IsNumeric(obj, ref d)) { max = (d >= max) ? d : max; } else { return “”; } } if (Double.NegativeInfinity == max) { return “”; } else { return max.ToString(System.Globalization.CultureInfo.InvariantCulture); } } |
||
XSLT 1.0 Equivalent: (none) |
||
XSLT 2.0 Equivalent: Use the max(number, number, …) function Note: in XSLT 1.0 you could write a fairly complicated XPath statement to achieve this |
||
|
|
|
Generates: C# |
Has XSLT Equivalent: in 2.0 only |
|
Emitted Code: public string MathMin(string param0, string param1) { double min = Double.PositiveInfinity; System.Collections.ArrayList listValues = new System.Collections.ArrayList(); listValues.Add(param0); listValues.Add(param1); foreach (string obj in listValues) { double d = 0; if (IsNumeric(obj, ref d)) { min = (d < min) ? d : min; } else { return “”; } } if (Double.PositiveInfinity == min) { return “”; } else { return min.ToString(System.Globalization.CultureInfo.InvariantCulture); } } |
||
XSLT 1.0 Equivalent: (none) |
||
XSLT 2.0 Equivalent: Use the min(number, number, …) function Note: in XSLT 1.0 you could write a fairly complicated XPath statement to achieve this |
||
|
|
|
Generates: C# |
Has XSLT Equivalent: in 1.0 and 2.0 |
|
Emitted Code: public string MathMod(string val, string denominator) { string retval = “”; double v = 0; double d = 0; if (IsNumeric(val, ref v) && IsNumeric(denominator, ref d)) { if (d != 0) { retval = Convert.ToString(v % d, System.Globalization.CultureInfo.InvariantCulture); } } return retval; } |
||
XSLT 1.0 Equivalent: Use the “mod” operator e.g. number mod number |
||
XSLT 2.0 Equivalent: Use the “mod” operator e.g. number mod number |
||
|
|
|
Generates: C# |
Has XSLT Equivalent: in 1.0 and 2.0 |
|
Emitted Code: Note: there will be one overload per unique number of parameters. Here we show an example with two input parameters. public string MathMultiply(string param0, string param1) { System.Collections.ArrayList listValues = new System.Collections.ArrayList(); listValues.Add(param0); listValues.Add(param1); double ret = 1; bool first = true; foreach (string obj in listValues) { double d = 0; if (IsNumeric(obj, ref d)) { if (first) { first = false; ret = d; } else { ret *= d; } } else { return “”; } } return ret.ToString(System.Globalization.CultureInfo.InvariantCulture); } |
||
XSLT 1.0 Equivalent: Use the “*” operator e.g. ((number * number) |
||
XSLT 2.0 Equivalent: Use the “*” operator e.g. ((number * number) |
||
|
|
|
Generates: C# |
Has XSLT Equivalent: in 1.0 and 2.0 |
|
Emitted Code: public string MathRound(string val) { return MathRound(val, “0”); } public string MathRound(string val, string decimals) { string retval = “”; double v = 0; double db = 0; if (IsNumeric(val, ref v) && IsNumeric(decimals, ref db)) { try { int d = (int)db; double ret = Math.Round(v, d); retval = ret.ToString(System.Globalization.CultureInfo.InvariantCulture); } catch (Exception) { } } return retval; } |
||
XSLT 1.0 Equivalent: round(number) |
||
XSLT 2.0 Equivalent: round(number) Note: the XSLT round() function does not take a second parameter – all number are rounded to 0 decimal places. You can achieve rounding to x dp’s through use of the format-number(number, string) function: e.g. format-number(3.55555, ‘#.00’) – but be aware that rounding in this way might not always give the result you’re looking for e.g. 9.2850 rounds to 9.28 using format-number() (although this can be coded around in XSLT). |
||
|
|
|
Generates: C# |
Has XSLT Equivalent: No |
|
Emitted Code: public string MathSqrt(string val) { string retval = “”; double d = 0; if (IsNumeric(val, ref d)) { if (d >= 0) { double ret = Math.Sqrt(d); retval = ret.ToString(System.Globalization.CultureInfo.InvariantCulture); } } return retval; } |
||
XSLT 1.0 Equivalent: (none) |
||
XSLT 2.0 Equivalent: (none) Note: A square-root can be calculated using an XSLT template – see here for an example. |
||
|
||
Generates: C# |
Has XSLT Equivalent: in 1.0 and 2.0 |
|
Emitted Code: Note: there will be one overload per unique number of parameters. Here we show an example with two input parameters. public string MathSubtract(string param0, string param1) { System.Collections.ArrayList listValues = new System.Collections.ArrayList(); listValues.Add(param0); listValues.Add(param1); double ret = 0; bool first = true; foreach (string obj in listValues) { if (first) { first = false; double d = 0; if (IsNumeric(obj, ref d)) { ret = d; } else { return “”; } } else { double d = 0; if (IsNumeric(obj, ref d)) { ret -= d; } else { return “”; } } } return ret.ToString(System.Globalization.CultureInfo.InvariantCulture); } |
||
XSLT 1.0 Equivalent: Use the “-” operator e.g. ((number – number) |
||
XSLT 2.0 Equivalent: Use the “-” operator e.g. ((number – number) |
||
Common Code (this is common code used by all the mathematical functoids) |
||
public bool IsNumeric(string val) { if (val == null) { return false; } double d = 0; return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d); } public bool IsNumeric(string val, ref double d) { if (val == null) { return false; } return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d); } |