예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
 static void Print(RationalTypes.Rational r)
 {
     Console.WriteLine(String.Concat(r.ToString(), "\t", r.ToSignedString(), "\t", r.DecimalApproximation));
 }