using System;
using System.Collections.Generic;
using System.Text;
namespace math_net
{
public static class Expression
{
// evals a function
public static string Eval(string expression)
{
int openPos;
int length;
string[] signs = { "^", "*", "/", "+" };
expression = expression.Replace(".", ",");
while (expression.Contains("("))
{
openPos = expression.IndexOf("(") + 1;
length = expression.LastIndexOf(")") - (openPos);
expression = expression.Substring(0, openPos - 1) +
Eval(expression.Substring(openPos, length)) +
expression.Substring(openPos + length + 1);
}
foreach (string sign in signs)
{
expression = MakeOperations(expression, sign);
}
return expression;
}
// gets the left value of a basic operation
private static double GetLeftPart(string expression, int posSign)
{
int length = 1;
double part;
while (IsPartNumeric(expression, posSign - (length + 1), length + 1))
{
length++;
}
part = double.Parse(expression.Substring(posSign - length, length));
return part;
}
// gets the right value of a basic operation
private static double GetRightPart(string expression, int posSign)
{
int length = 1;
double part;
while (IsPartNumeric(expression, posSign + 1, length + 1))
{
length++;
}
part = double.Parse(expression.Substring(posSign + 1, length));
return part;
}
// checks if a string has a numeric value
private static bool IsNumeric(string expression)
{
Char[] chars = expression.ToCharArray();
for(int i = 0; i < chars.Length; i++)
{
if (!char.IsNumber(chars[i]) && chars[i].ToString() != ",")
{
if (chars[i].ToString() != "-" && i != 0)
{
return false;
}
}
}
return true;
}
// checks if a part of a string is numeric
private static bool IsPartNumeric(string expression, int start, int length)
{
if ((start) < 0 || length > expression.Length - start)
{
return false;
}
return IsNumeric(expression.Substring(start, length));
}
// returns the specified basic operation
private static double Operate(double firstValue, double secondValue,
string sign)
{
switch (sign)
{
case "^":
if (!(IsInteger(secondValue)) && (firstValue < 0))
{
// i result
throw new ArgumentOutOfRangeException();
}
return Math.Pow(firstValue, secondValue);
case "*":
return firstValue * secondValue;
case "/":
if (secondValue == 0)
{
// infinite result
throw new ArgumentOutOfRangeException();
}
return firstValue / secondValue;
case "+":
return firstValue + secondValue;
}
return 0;
}
//checks if a double var has a integer number
private static bool IsInteger(double value)
{
return (double)((int)value) == value;
}
// makes all of the operations for the specified sign in a expression
// whithout parenthesis
private static string MakeOperations(string expression, string sign)
{
int signPos;
double firstValue;
double secondValue;
double result;
string operation;
if (sign == "+")
{
// converts substractions into sums
expression = expression.Replace("+-", "-");
expression = expression.Replace("-", "+-");
// if there's no value in front of the first + adds a 0
if (expression.StartsWith("+"))
{
expression = "0" + expression;
}
}
// makes all of the operations for the specified sign
while (expression.Contains(sign))
{
signPos = expression.IndexOf(sign);
firstValue = GetLeftPart(expression, signPos);
secondValue = GetRightPart(expression, signPos);
operation = firstValue.ToString() + sign + secondValue.ToString();
result = Operate(firstValue, secondValue, sign);
expression = expression.Replace(operation, result.ToString());
}
return expression;
}
}
}