public void SubstituteOperationsWithResult(ref string calculationString, string symbol) { do { if (!calculationString.Contains(symbol)) { break; } // Break if Negative Result, with no other calculations eg. -50 if (symbol == OperatorSymbol.Subtract && calculationString.Substring(0, 1) == symbol && !calculationString.Substring(1).Contains(symbol)) { break; } // Break if Double Negative Result, with no other calculations eg. --50 if (symbol == OperatorSymbol.Subtract && calculationString.Substring(0, 2) == (symbol + symbol) && !calculationString.Substring(2).Contains(symbol)) { calculationString = calculationString.Replace((symbol + symbol), ""); break; } string operationString = _operationIdentifier.GetNextOperationMatch(calculationString, symbol); IOperator Operation = _operationFactory.Create(operationString); decimal Result = Operation.GetResult(); calculationString = calculationString.Replace(operationString, Result.ToString()); }while (calculationString.Contains(symbol)); }
/// <summary> /// A method which calculates a given expression.</summary> /// <param name="separated"> A infix notation expression InputElement list</param> /// <returns> A calculation result status </returns> private CalculateResult Calculate(IEnumerable <InputElement> separated) { Status = WorkingStatus.ERROR; if (separated.Count() < 1) { Result = 0; Status = WorkingStatus.WORKING; return(new CalculateSuccess()); } if (separated.Last() is Point) { return(new CalculateFailed()); } IList <InputElement> temp = new List <InputElement>(separated); { int res = 0; foreach (var item in temp) { if (item.CompareTo("(") == 0) { res += 1; } else if (item.CompareTo(")") == 0) { res -= 1; } } for (int i = 0; i < res; i++) { temp.Add(new CloseBracket()); } } Queue <InputElement> postfix = new Queue <InputElement>(); if (ChangeToPostfix(temp, out postfix) == false) { return(new CantCalculateInvalidFormat()); } Stack <string> operand = new Stack <string>(); try { while (postfix.Count > 0) { InputElement token = postfix.Dequeue(); if (token is Literal) { operand.Push(token.GetElement); } else { IOperator op = OperatorsPriority[token]; string op1; string op2; double _op1 = 0; double _op2 = 0; if (op is IBinaryOperator) { op2 = operand.Pop(); op1 = operand.Pop(); if (GetDoubleValue(op2, out _op2) == false || GetDoubleValue(op1, out _op1) == false) { return(new CantCalculateInvalidFormat()); } if ((op is Models.Point) == false) { LastOperand = new Literal(op2); LastOperator = op; } } else if (op is IUnaryOperator) { op1 = operand.Pop(); if (GetDoubleValue(op1, out _op1) == false) { return(new CantCalculateInvalidFormat()); } } double result = 0; op.GetResult(_op1, _op2, out result); if (Double.IsInfinity(result) || Double.IsNaN(result)) { return(new CantCalculateTooBigNumber()); } // Exceptional Case : % if (op.ToString().CompareTo("%") == 0) { if (operand.Count > 0) { if (postfix.Count == 0 || (postfix.Count > 0 && postfix.Peek().CompareTo("/") != 0 && postfix.Peek().CompareTo("*") != 0)) { double prevLiteral = Double.Parse(operand.Peek()); result = prevLiteral * result; } } } operand.Push(result.ToString()); } } } catch (Exception e) { if (e is InvalidOperationException || e is InvalidNumberException) { return(new CantCalculateInvalidFormat()); } else if (e is DivideByZeroException) { return(new CantDivideByZero()); } else if (e is TooBigNumberException) { return(new CantCalculateTooBigNumber()); } return(new CalculateFailed()); } double ret; if (operand.Count == 0 || Double.TryParse(operand.Peek(), out ret) == false) { return(new CalculateFailed()); } Result = ret; Status = WorkingStatus.WORKING; return(new CalculateSuccess()); }
/// <summary> /// The method calculates result for given expression. /// </summary> /// <param name="separated"> InputElement list in infix notation</param> /// <returns> Calculation result status </returns> private CalculationResult Calculate(IEnumerable <InputElement> separated) { Status = WorkingStatus.ERROR; if (!separated.Any()) { Result = 0; Status = WorkingStatus.WORKING; return(new CalculationSuccessful()); } if (separated.Last() is Point) { return(new CalculationFailed()); } IList <InputElement> temp = new List <InputElement>(separated); // This section adds missing closing brackets { int depth = 0; foreach (var item in temp) { if (item.CompareTo("(") == 0) { depth += 1; } else if (item.CompareTo(")") == 0) { depth -= 1; } } for (int i = 0; i < depth; i++) { temp.Add(new CloseBracket()); } } Queue <InputElement> postfix; if (!ChangeToPostfix(temp, out postfix)) { return(new CantCalculateInvalidFormat()); } Stack <string> operand = new Stack <string>(); try { foreach (var token in postfix) { if (token is Literal) { operand.Push(token.GetElement); } else { IOperator op = OperatorDescriptions[token]; string op1; string op2; double _op1 = 0; double _op2 = 0; // This section retrives arguments needed by operator if (op is IBinaryOperator) { op2 = operand.Pop(); op1 = operand.Pop(); if (!GetDoubleValue(op2, out _op2) || !GetDoubleValue(op1, out _op1)) { return(new CantCalculateInvalidFormat()); } if ((op is Models.Point) == false) { LastOperand = new Literal(op2); LastOperator = op; } } else if (op is IUnaryOperator) { op1 = operand.Pop(); if (!GetDoubleValue(op1, out _op1)) { return(new CantCalculateInvalidFormat()); } } op.GetResult(_op1, _op2, out double result); if (Double.IsInfinity(result) || Double.IsNaN(result)) { return(new CantCalculateTooBigNumber()); } operand.Push(result.ToString()); } } } catch (DivideByZeroException) { return(new CantDivideByZero()); } catch (InvalidOperationException) { return(new CantCalculateInvalidFormat()); } catch (Exception e) { System.Diagnostics.Debug.WriteLine(e.Message); return(new CalculationFailed()); } double ret; if (operand.Count == 0 || Double.TryParse(operand.Peek(), out ret) == false) { return(new CalculationFailed()); } Result = ret; Status = WorkingStatus.WORKING; return(new CalculationSuccessful()); }