/// <summary> /// Will create tree from given equation string /// </summary> /// <param name="equation">string containing equation</param> /// <returns>valid tree or throw exception</returns> private Tree CreateTree(string equation) { Tree tree = new Tree(); // if is equation inside brackets -> remove them while (equation != string.Empty && equation.First() == '(' && equation.Last() == ')') { equation = RemoveBracketsStartingOnIndex(equation, 0); } // if there is nothing if (equation == string.Empty) { _error = ErrorsEnum.OperatorDoNotHaveEnoughArguments; throw new SyntaxErrorException(); } // get index of operator with highest priority for tree (lowest priority) int opIndex = GetIndexOfOperatorWithLowestPriority(equation); if (opIndex == -1) { // there is no more operators tree.IsOperator = false; tree.Number = StringToDouble(equation, ref _error); } else { // set operator into tree OperatorsEnum op = GetOperatorOnIndex(equation, opIndex); tree.IsOperator = true; tree.Op = op; if (Operators.IsSingleNumberOperator(op)) { // single argument operator -> setup only left side of tree // opIndex should be 0 because double arguments operators are solved before single arg. o. // -> single ar. o. is the last outside brackets (or there is only last number - argument for operator) if (opIndex != 0) { _error = ErrorsEnum.UnknownError; throw new SyntaxErrorException(); } equation = equation.Substring(Operators.GetOperatorFromEnum(op).Length); tree.Left = CreateTree(equation); } else { // double arguments operator -> setup both left and right side of tree string equationLeft = equation.Substring(0, opIndex); string equationRight = equation.Substring(opIndex + Operators.GetOperatorFromEnum(op).Length); tree.Left = CreateTree(equationLeft); tree.Right = CreateTree(equationRight); } } return(tree); }
/// <summary> /// will solve equation with one operator /// </summary> /// <param name="o">operator</param> /// <param name="argument1">first argument value</param> /// <param name="argument2">second argument value</param> /// <param name="inRadians">for trigonometric fcs</param> /// <param name="error">will be set, if an error occured</param> /// <returns>Result of equation if success or null if fail</returns> public static double SolveOperator(OperatorsEnum o, double?argument1, double?argument2, bool inRadians, ref ErrorsEnum error) { // check if required arguments has value if (!IsSingleNumberOperator(o) && !argument2.HasValue || !argument1.HasValue) { throw new SyntaxErrorException(); // shouldn't happened - fixed before solving tree } // solve based on operator switch (o) { // disable ReSharper warning, which is solved by first condition // ReSharper disable PossibleInvalidOperationException case OperatorsEnum.Plus: return(argument1.Value + argument2.Value); case OperatorsEnum.Minus: return(-argument1.Value); case OperatorsEnum.Multiply: return(argument1.Value * argument2.Value); case OperatorsEnum.Pow: return(Calculations.Pow(argument1.Value, argument2.Value)); case OperatorsEnum.Sqrt: return(Calculations.Sqrt(argument1.Value, argument2.Value)); case OperatorsEnum.Factorial: return(Calculations.Factorial(argument1.Value)); case OperatorsEnum.Modulo: return(argument1.Value % argument2.Value); case OperatorsEnum.Sinus: return(Calculations.Sin(argument1.Value, inRadians)); case OperatorsEnum.Cosinus: return(Calculations.Cos(argument1.Value, inRadians)); case OperatorsEnum.Tangents: return(Calculations.Tan(argument1.Value, inRadians)); case OperatorsEnum.Cotangents: return(Calculations.Ctg(argument1.Value, inRadians)); case OperatorsEnum.Asinus: return(Calculations.Asin(argument1.Value, inRadians)); case OperatorsEnum.Acosinus: return(Calculations.Acos(argument1.Value, inRadians)); case OperatorsEnum.Atangents: return(Calculations.Atan(argument1.Value, inRadians)); case OperatorsEnum.Acotangents: return(Calculations.Actg(argument1.Value, inRadians)); case OperatorsEnum.Divide: // can't divide by 0 if (argument2.Value.Equals(0)) { error = ErrorsEnum.CantDivideByZero; throw new InvalidDataException(); } return(argument1.Value / argument2.Value); } // if operator is not in the list throw new SyntaxErrorException(); // shouldn't happened - fixed before solving tree }
/// <summary> /// </summary> /// <param name="op">operator</param> /// <returns>True if operator is any function operator. Else return false.</returns> public static bool IsFunctionOperator(OperatorsEnum op) { foreach (OperatorsEnum o in FunctionsOperators) { if (o == op) { return(true); } } return(false); }
/// <summary> /// will check sequence of operators /// </summary> /// <param name="str">string containing operators</param> /// <returns>true if string contains valid sequence of operators</returns> private bool CheckStringOfOperators(string str) { int i = 0; List <List <OperatorsEnum> > listOfOperators = new List <List <OperatorsEnum> > { new List <OperatorsEnum>() }; str = str.Replace(Strings.Minus, string.Empty); while (i < str.Length) { if (str[i] == '(' || str[i] == ')') { while (i < str.Length && (str[i] == '(' || str[i] == ')')) { ++i; } listOfOperators.Add(new List <OperatorsEnum>()); } else { OperatorsEnum o = Operators.GetOperator(str.Substring(i)); if (o == OperatorsEnum.None) { return(false); } listOfOperators.Last().Add(o); i += Operators.GetOperatorFromEnum(o).Length; } } foreach (List <OperatorsEnum> operators in listOfOperators) { if (!CheckStringOfOperators(operators)) { return(false); } } return(true); }
/// <summary> /// </summary> /// <param name="o">operator</param> /// <returns>string which represents given operator.</returns> public static string GetOperatorFromEnum(OperatorsEnum o) { switch (o) { case OperatorsEnum.Plus: return(Strings.Plus); case OperatorsEnum.Minus: return(Strings.Minus); case OperatorsEnum.Multiply: return(Strings.Multiply); case OperatorsEnum.Divide: return(Strings.Divide); case OperatorsEnum.Pow: return(Strings.Pow); case OperatorsEnum.Sqrt: return(Strings.Sqrt); case OperatorsEnum.Factorial: return(Strings.Factorial); case OperatorsEnum.Modulo: return(Strings.Modulo); case OperatorsEnum.Sinus: return(Strings.Sinus); case OperatorsEnum.Cosinus: return(Strings.Cosinus); case OperatorsEnum.Tangents: return(Strings.Tangents); case OperatorsEnum.Cotangents: return(Strings.Cotangents); case OperatorsEnum.Asinus: return(Strings.Asinus); case OperatorsEnum.Acosinus: return(Strings.Acosinus); case OperatorsEnum.Atangents: return(Strings.Atangents); case OperatorsEnum.Acotangents: return(Strings.Acotangents); } return(string.Empty); }
/// <summary> /// </summary> /// <param name="o">operator</param> /// <returns>True if operator requires only one argument.</returns> public static bool IsSingleNumberOperator(OperatorsEnum o) { return(OperatorsPriority1.Contains(o)); }
public ComparaisonCode(OperatorsEnum type) { this.type = type; }
public LogicExpression(String theOperator, IExpressions expression1, IExpressions expression2) { this.operatorType = getOperatorType(theOperator); this.firstExpression = expression1; this.secondExpression = expression2; }
public BooleanExpression(string myOperator, IExpressions expression1, IExpressions expression2) { this.operatorType = getOperatorType(myOperator); this.firstExpression = expression1; this.secondExpression = expression2; }
/** * The constructor * @param operatorType The type of the operator for current arithmetic expression * @param firstExpression The first expression * @param secondExpression The second expression */ public ArithmeticExpression(string operatorType, IExpressions firstExpression, IExpressions secondExpression) { this.operatorType = getOperatorType(operatorType); this.firstExpression = firstExpression; this.secondExpression = secondExpression; }