public static double Solve(Function function, double x) { Stack P = new Stack(); double s = 0; double a, b; for (int i = 0; i < function.RPNsequence.Length; i++) { if (string.IsNullOrEmpty(function.RPNsequence[i])) continue; else { if (char.IsDigit(function.RPNsequence[i][0])) { P.Push(function.RPNsequence[i]); } else if ((char.IsLetter(function.RPNsequence[i][0])) && (function.RPNsequence[i][0] != function.Argument) && (function.RPNsequence[i][0] != '\u03c0') && (function.RPNsequence[i][0] != 'e')) { double X = Convert.ToDouble(P.Pop()); switch (function.RPNsequence[i]) { case "sqrt": P.Push(Math.Sqrt(X)); break; case "abs": P.Push(Math.Abs(X)); break; case "sin": P.Push(Math.Sin(X)); break; case "sinh": P.Push(Math.Sinh(X)); break; case "cosh": P.Push(Math.Cosh(X)); break; case "cos": P.Push(Math.Cos(X)); break; case "cth": P.Push(1 / Math.Tanh(X)); break; case "tanh": P.Push(Math.Tanh(X)); break; case "tan": P.Push(Math.Tan(X)); break; case "cot": P.Push(1 / Math.Tan(X)); break; case "аbs": P.Push(Math.Abs(X)); break; case "ln": P.Push(Math.Log(X)); break; case "arsinh": P.Push(Math.Log(X + Math.Sqrt(X * X + 1))); break; case "arcsin": P.Push(Math.Asin(X)); break; case "arcosh": P.Push(Math.Log(X + Math.Sqrt(X + 1) * Math.Sqrt(X - 1))); break; case "arccos": P.Push(Math.Acos(X)); break; case "artanh": P.Push(Math.Log((X + 1) / (X - 1)) / 2); break; case "arccot": P.Push(Math.Atan(-1 * X) + Math.PI / 2); break; case "arcth": P.Push(Math.Log((X + 1) / (1 - X)) / 2); break; case "arctan": P.Push(Math.Atan(X)); break; case "log": P.Push(Math.Log(Convert.ToDouble(P.Pop()), X)); break; case "sign": P.Push(Math.Sign(X)); break; case "rem": P.Push(Convert.ToDouble(P.Pop()) % X); break; case "sec": P.Push(1 / Math.Cos(x)); break; case "csc": P.Push(1 / Math.Sin(x)); break; case "arcsec": P.Push(Math.Acos(1 / X)); break; case "arccsc": P.Push(Math.Asin(1 / X)); break; case "sech": P.Push(1 / Math.Cosh(x)); break; case "csch": P.Push(1 / Math.Sinh(x)); break; case "arsech": P.Push(Math.Log(1 / x + Math.Sqrt(1 / x + 1) * Math.Sqrt(1 / x - 1))); break; case "arcsch": P.Push(Math.Log(1 / x + Math.Sqrt(1 / x * x + 1))); break; } } else { if (function.RPNsequence[i][0] == 'e') P.Push(Math.E); else if (function.RPNsequence[i][0] == '\u03c0') P.Push(Math.PI); else if (function.RPNsequence[i][0] == function.Argument) P.Push(x); else { b = Convert.ToDouble(P.Pop()); a = Convert.ToDouble(P.Pop()); switch (function.RPNsequence[i][0]) { ///binary operations case '+': P.Push(a + b); break; case '-': P.Push(a - b); break; case '*': P.Push(a * b); break; case '/': P.Push(a / b); s = b; break; case '^': if (b > 1) { if ((a < 0) || (a > 0)) { P.Push(Math.Pow(a, b)); } else { P.Push(0); } } else if ((b < 1) && (b > 0)) { if (a > 0) { P.Push(Math.Pow(a, b)); } else if (a < 0) { if (s % 2 == 1) { P.Push(-Math.Pow(Math.Abs(a), b)); } else P.Push(Math.Pow(a, b)); } else { P.Push(0); } } else if (b == 1) { P.Push(a); } else if (b == 0) { if (a == 0) { P.Push(0); } else P.Push(1); } break; case ';': P.Push(b); P.Push(a); break; ///unary operations case '~': P.Push(a); P.Push(-1 * Convert.ToDouble(b)); break; default: goto y; }//end switch }//end else } } } y: return Convert.ToDouble(P.Pop()); }
private void ConvertToRPN() { if (name[0] == '-') { name.Remove(0, 1); name.Insert(0, '~'); } name.Replace("(-", "(~"); Stack S = new Stack(); RPNsequence = new string[name.Length]; int j = 0; ///Перевод выражения в польскую запись string function = string.Empty; int e = 0; for (; j < name.Length; j++) { if ((char.IsDigit(name[j])) || (name[j] == '\u03c0') || (name[j] == 'e') || (name[j] == Argument))//в буфере число? { RPNsequence[e] += name[j]; if ((j != name.Length - 1) && (!char.IsDigit(name[j + 1]))) e++; } else if ((char.IsLetter(name[j])) && (name[j] != Argument) && (name[j] != '\u03c0') && (name[j] != 'e')) { while (char.IsLetter(name[j])) { function += name[j]; j++; } j--; S.Push(function); function = string.Empty; } else if (name[j] == ';') { continue; } else { if (S.IsEmpty() == true) { S.Push(name[j]); } else if (GetPriority(Convert.ToString(S.CopyElement())) < GetPriority(name[j].ToString())) //сравнение приоритетов операций { S.Push(name[j]); } /// else if (name[j] == '(') { S.Push(name[j]); } else if (name[j] == ')') { while (GetPriority(Convert.ToString(S.CopyElement())) != 1) { RPNsequence[e] += S.Pop().ToString(); e++; } S.DeleteElement(); } else { while (GetPriority(Convert.ToString(S.CopyElement())) >= GetPriority(name[j].ToString())) { RPNsequence[e] += S.Pop().ToString(); e++; } S.Push(name[j]); } } } while (S.IsEmpty() != true) { e++; RPNsequence[e] += S.Pop().ToString(); } }