public static void Demo() { var v1 = new RationalTypes.Rational(1561384532, 456456378); var v2 = new RationalTypes.Rational(789, 756); Print(v1); Print(v2); Print(v1 + v2); Print(v1 - v2); Print(v1 * v2); Print(v1 / v2); }
public static Rational Evaluate(string expression) { if (expression.Length == 0) { throw new Exception("No content."); } if (expression[0] == '*' || expression[0] == '/') { throw new Exception("Invalid beginning."); } if (expression[expression.Length - 1] == '*' || expression[expression.Length - 1] == '/' || expression[expression.Length - 1] == '-' || expression[expression.Length - 1] == '+') { throw new Exception("Invalid ending."); } bool wasNumber = false; List <Element> elements = new List <Element>(); for (int i = 0; i < expression.Length;) { switch (expression[i]) { case '(': { i++; StringBuilder builder = new StringBuilder(); int indent = 1; while (i < expression.Length) { if (expression[i] == ')') { indent--; if (indent == 0) { break; } } else if (expression[i] == '(') { indent++; } builder.Append(expression[i++]); } i++; elements.Add(new Element { Type = ElType.Numeric, value = Evaluate(builder.ToString()) }); wasNumber = false; break; } case '+': case '-': elements.Add(new Element { Type = ElType.Sign, value = expression[i] }); i++; wasNumber = false; break; case '*': i++; wasNumber = false; break; case '/': elements.Add(new Element { Type = ElType.Div }); i++; wasNumber = false; break; case ' ': i++; break; default: { StringBuilder builder = new StringBuilder(); while (i < expression.Length && expression[i] != '+' && expression[i] != '-' && expression[i] != '*' && expression[i] != '/' && expression[i] != '(' && expression[i] != ')' && expression[i] != ' ') { builder.Append(expression[i++]); } if (wasNumber) { throw new Exception("Repeating numerics."); } elements.Add(new Element { Type = ElType.Numeric, value = Rational.Parse(builder.ToString()) }); wasNumber = true; break; } } } Rational value = (Rational)0; Rational mulvalue = (Rational)0; SByte sign = 1; for (int i = 0; i < elements.Count;) { switch (elements[i].Type) { case ElType.Sign: value += mulvalue; mulvalue = (Rational)0; if (sign != 0 && i > 0) { throw new Exception("Repeating signs."); } if ((char)elements[i].value == '-') { sign = -1; } else if ((char)elements[i].value == '+') { sign = 1; } i++; break; case ElType.Numeric: mulvalue += (Rational)elements[i].value * sign; if (sign == 0) { mulvalue *= (Rational)elements[i].value; } sign = 0; i++; break; case ElType.Mul: mulvalue *= (Rational)elements[i + 1].value; i += 2; break; case ElType.Div: if (elements[i + 1].Type != ElType.Numeric) { throw new Exception("Repeating operators."); } mulvalue /= (Rational)elements[i + 1].value; i += 2; break; } } value += mulvalue; return(value); }
public Rational Pow(Rational Exponent) { if (Exponent <= 0 && this == 0) { throw new DivideByZeroException(); } else if (Exponent == 0) { if (this == 0) { throw new DivideByZeroException(); } return((Rational)1); } else if (this == 0) { return((Rational)0); } else if (this < 0 && (Exponent.Denominator & 1) == 0) { throw new ComplexResultException(); } long l = 0, r = Math.Abs(Numerator); long i = (Math.Abs(Numerator) + 1) / 2; long _n = 0, _d = 0; while (l < r) { try { if (Utility.Pow(i, Exponent.Denominator) > Math.Abs(Numerator)) { r = i - 1; } else if (Utility.Pow(i, Exponent.Denominator) < Math.Abs(Numerator)) { l = i; } else { _n = i; break; } } catch { r = i - 1; } finally { i = (l + r + 1) / 2; } } if (_n == 0) { throw new IrrationalResultException(); } l = 0; r = Denominator; i = (Denominator + 1) / 2; while (l < r) { try { if (Utility.Pow(i, Exponent.Denominator) > Denominator) { r = i - 1; } else if (Utility.Pow(i, Exponent.Denominator) < Denominator) { l = i; } else { _d = i; break; } } catch { r = i - 1; } finally { i = (l + r + 1) / 2; } } if (_d == 0) { throw new IrrationalResultException(); } var res = new Rational(Utility.Pow(Sgn * _n, Math.Abs(Exponent.Numerator)), Utility.Pow(_d, Math.Abs(Exponent.Numerator))); if (Exponent > 0) { return(res); } else { return(res.Inverse); } }
static void Print(RationalTypes.Rational r) { Console.WriteLine(String.Concat(r.ToString(), "\t", r.ToSignedString(), "\t", r.DecimalApproximation)); }