private decimal CalculateSegment(string Formula) { try { string[] arr; #region Validate Formula if (!Validate(Formula)) { return(0); } #endregion #region Clean Formula //Remove whitespace Formula = Formula.Replace(" ", ""); //Check for double variables (AB becomes A*B) arr = Formula.Split("/+-*%^0123456789().,".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); while (CheckForDoubleVariables(arr)) { foreach (string s in arr) { if (s.Replace("()", "").Replace(")", "").Length > 1 && !IsReservedWord(s)) { Formula = Formula.Replace(s, s.Insert(1, "*")); arr = Formula.Split("/+-*%^0123456789().,".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); break; } } } //Check for a number in front of a variable (5X becomes 5*X) arr = Formula.Split("/+-*%^(),".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); foreach (string s in arr) { int intNumberIndex = s.LastIndexOfAny("0123456789.".ToCharArray()); if (intNumberIndex > -1 && intNumberIndex + 1 < s.Length) { Formula = Formula.Replace(s, s.Insert(intNumberIndex + 1, "*")); arr = Formula.Split("/+-*%^()".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); } } #endregion #region Solve Functions in Formula // abs(x) becomes {abs[x]} #region Find Functions arr = Formula.Split("()".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < arr.Length; i++) { if (IsFunction(CleanFunction(arr[i]))) { arr[i] = CleanFunction(arr[i]); int intSkip = 0; int intIndexOfFunctionStart = Formula.IndexOf(arr[i] + "("); Formula = StringFunctions.ReplaceOnce(Formula, arr[i] + "(", "{" + arr[i] + "["); for (int i2 = intIndexOfFunctionStart; i2 < Formula.Length; i2++) { if (Formula[i2] == '(') { intSkip++; } if (Formula[i2] == ')') { intSkip--; } if (Formula[i2] == ')' && intSkip < 0) { Formula = Formula.Remove(i2, 1); Formula = Formula.Insert(i2, "]}"); break; } } } } #endregion // {abs[x]} becomes 345 etc.. arr = Formula.Split("{}".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); while (Formula.Contains("[")) { foreach (string strSegment in arr) { if (strSegment.Contains("[") && strSegment.Contains("]")) { if (IsFunction(CleanFunction(strSegment))) { Functions.IMathFunction objFunction = GetFunction(CleanFunction(strSegment)); Formula = Formula.Replace("{" + strSegment + "}", objFunction.Solve(GetParams(strSegment)).ToString()); arr = Formula.Split("{}".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); } } } } #endregion #region Insert Constants into Formula // Pi becomes 3.14.... arr = Formula.Split("/+-*%^".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); foreach (string s in arr) { if (s.Contains("(") && !s.Contains(")")) { s.Replace("(", ""); } if (s.Contains(")") && !s.Contains("(")) { s.Replace(")", ""); } foreach (KeyValuePair <string, object> objReservedWord in _objConstants) { if (objReservedWord.Key.Length > 1) { if (s.ToLower() == objReservedWord.Key.ToLower() || s.ToLower() == objReservedWord.Key.ToLower() + "()") { Formula = Formula.Replace(s, objReservedWord.Value.ToString()); } } else { if (s.ToLower() == objReservedWord.Key.ToLower() + "()") { Formula = Formula.Replace(s, objReservedWord.Value.ToString()); } else if (s.ToLower() == objReservedWord.Key.ToLower() && ( s == objReservedWord.Key.ToLower() || !Parameters.Keys.Contains((ParameterKey)Enum.Parse(typeof(ParameterKey), s.ToUpper())) ) ) { Formula = Formula.Replace(s, objReservedWord.Value.ToString()); } } } } #endregion #region Insert Variables into Formula // A becomes 2 etc... arr = Formula.Split("/+-*%^()[]{}".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); foreach (KeyValuePair <ParameterKey, object> de in _objParameters) { foreach (string s in arr) { if (s.ToUpper() != de.Key.ToString() && s.ToUpper().EndsWith(de.Key.ToString())) { if (de.Value.GetType() == typeof(decimal[])) { throw new ArgumentException("Cannot do this! (" + s + ")"); } else { Formula = Formula.Replace(s, (Convert.ToDecimal(s.Replace(de.Key.ToString(), "")) * SqlConvert.ToDecimal(de.Value)).ToString()); } } } Formula = Formula.Replace(de.Key.ToString(), de.Value.ToString()); Formula = Formula.Replace(de.Key.ToString().ToLower(), de.Value.ToString()); } //Make sure there are no variables left arr = Formula.Split("/+-*%^0123456789().".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); if (arr.Length > 0) { string strUnassignedVariables = String.Empty; foreach (string s in arr) { strUnassignedVariables += s + ", "; } strUnassignedVariables = StringFunctions.Shave(strUnassignedVariables, 2); throw new ArithmeticException("Forumla contains variables that are unassigned: " + strUnassignedVariables); } #endregion #region Calculate Parenthetic portions of Formula // (4 * 7) becomes 28 etc... while (Formula.LastIndexOf("(") > -1) { int lastOpenParenthesisIndex = Formula.LastIndexOf("("); int firstCloseParenthesisIndexAfterLastOpened = Formula.IndexOf(")", lastOpenParenthesisIndex); decimal result = ProcessOperation(Formula.Substring(lastOpenParenthesisIndex + 1, firstCloseParenthesisIndexAfterLastOpened - lastOpenParenthesisIndex - 1)); bool AppendAsterix = false; if (lastOpenParenthesisIndex > 0) { if (Formula.Substring(lastOpenParenthesisIndex - 1, 1) != "(" && !OperationOrder.Contains(Formula.Substring(lastOpenParenthesisIndex - 1, 1))) { AppendAsterix = true; } } Formula = Formula.Substring(0, lastOpenParenthesisIndex) + (AppendAsterix ? "*" : "") + result.ToString() + Formula.Substring(firstCloseParenthesisIndexAfterLastOpened + 1); } #endregion _strLastFormulaSimplified = Formula; return(ProcessOperation(Formula)); } catch (ArgumentException ex) { throw ex; } catch (ArithmeticException ex) { throw ex; } //catch (Exception ex) //{ //return Calculate(strOriginalFormula); //throw new Exception("Error Occured While Calculating. Check Syntax", ex); //} }