Ejemplo n.º 1
0
    public NumberClass Pow(NumberClass n)
    {
        if (n == One || this == One || this == Zero)
        {
            return(this);
        }
        if (n == Zero)
        {
            return(One);
        }
        if (exponent == 0 && n.exponent == 0)
        {
            return(Math.Pow(mantissa, n.mantissa));
        }

        var tempExpo = exponent + Math.Log10(mantissa);

        if (Math.Max(Math.Log10(exponent), 0) + n.exponent < 300)
        {
            tempExpo *= n.GetRealMantissa();
            return(tempExpo < 1e17
                ? new NumberClass(Math.Pow(10, tempExpo % 1), Math.Floor(tempExpo))
                : new NumberClass(mantissa, tempExpo));
        }

        tempExpo  = Math.Log10(tempExpo);
        tempExpo += n.exponent + Math.Log10(n.exponent);
        return(new NumberClass(mantissa, tempExpo));
    }
Ejemplo n.º 2
0
        public void TestVirtualCall()
        {
            var cls = new NumberClass(5);

            Assert.AreEqual(5, cls.Number, "#1");
            Assert.AreEqual(-5, cls.NegativeNumber, "#2");
        }
Ejemplo n.º 3
0
    protected override string FormatRaw(NumberClass nc)
    {
        if (nc.exponent <= beforeSciCut)
        {
            return($"{nc.GetRealMantissa():###,##0.##}");
        }
        var expExp = Math.Floor(Math.Log10(nc.exponent));

        var ext  = nc.exponent % 3;
        var nMan = nc.mantissa * Math.Pow(10, ext);
        var nExp = nc.exponent - ext;

        if (expExp <= beforeSciCutExponent)
        {
            return($"{nMan:##0.##}{e}{nExp:###,###}");
        }

        var expMan = nExp / Math.Pow(10, expExp);

        string GetMantissaIfReasonable() => expExp <= 15 ? $"{nMan:0.00}" : "";

        var expExt  = expExp % 3;
        var nExpMan = expMan * Math.Pow(10, expExt);
        var nExpExp = expExp - expExt;

        if (cutOff1E && expMan == 1)
        {
            return($"{GetMantissaIfReasonable()}{e}{e}{nExpExp:###,###}");
        }
        return($"{GetMantissaIfReasonable()}{e}{nExpMan:##0.00}{e}{nExpExp:###,###}");
    }
        public void For_IsGreaterThan_WhenValueGreaterThanMinValue_Then_NoValidationErrorIsReturned()
        {
            // Arrange:
            var numberValidator = new InlineValidator <NumberClass>();

            numberValidator.Setup(x => x.IntValue)
            .IsGreaterThan(0);
            numberValidator.Setup(x => x.FloatValue)
            .IsGreaterThan(0);
            numberValidator.Setup(x => x.DoubleValue)
            .IsGreaterThan(0);
            numberValidator.Setup(x => x.DecimalValue)
            .IsGreaterThan(0);

            var toValidate = new NumberClass
            {
                IntValue     = 1,
                FloatValue   = 1,
                DoubleValue  = 1,
                DecimalValue = 1m
            };

            // Act:
            var validationErrors = numberValidator.Validate(toValidate);

            // Assert:
            validationErrors.Count.Should().Be(0);
        }
Ejemplo n.º 5
0
        private void AddVariable(string varName, NumberClass valueType)
        {
            if (_variables.ContainsKey(varName))
            {
                throw new VariableAlreadyDefinedException(StringResources.Variable_already_defined + ": " + varName);
            }

            if (valueType.NumberType == NumberClass.NumberTypes.Expression)
            {
                SimplificationReturnValue eeVal;

                eeVal = EvaluateExpression(valueType);

                if (eeVal.ReturnType == SimplificationReturnValue.ReturnTypes.Float)
                {
                    AddVariable(varName, eeVal.DoubleValue);
                    return;
                }
                if (eeVal.ReturnType == SimplificationReturnValue.ReturnTypes.Integer)
                {
                    AddVariable(varName, eeVal.IntValue);
                    return;
                }
            }
            _variables.Add(varName, valueType);
        }
Ejemplo n.º 6
0
        private SimplificationReturnValue EvaluateExpression(NumberClass expression)
        {
            var parser = new Parser();

            foreach (var cfh in _customFunctions)
            {
                parser.AddCustomFunction(cfh.Key, cfh.Value);
            }

            foreach (var v in _variables)
            {
                if (v.Value.NumberType == NumberClass.NumberTypes.Float)
                {
                    parser.AddVariable(v.Key, v.Value.FloatNumber);
                }
                if (v.Value.NumberType == NumberClass.NumberTypes.Integer)
                {
                    parser.AddVariable(v.Key, v.Value.IntNumber);
                }
                if (v.Value.NumberType == NumberClass.NumberTypes.Expression)
                {
                    parser.AddVariable(v.Key, v.Value.Expression);
                }
            }

            foreach (var f in _functions)
            {
                parser.AddFunction(f.Name, f.Arguments, f.Expression);
            }
            return(parser.Simplify(expression.Expression));
        }
        public void For_IsGreaterThanOrEqualTo_WhenValueIsLessThanMinValue_Then_ValidationErrorIsReturned()
        {
            // Arrange:
            var numberValidator = new InlineValidator <NumberClass>();

            numberValidator.Setup(x => x.IntValue)
            .IsGreaterThanOrEqualTo(0);
            numberValidator.Setup(x => x.FloatValue)
            .IsGreaterThanOrEqualTo(0);
            numberValidator.Setup(x => x.DoubleValue)
            .IsGreaterThanOrEqualTo(0);
            numberValidator.Setup(x => x.DecimalValue)
            .IsGreaterThanOrEqualTo(0);

            var toValidate = new NumberClass
            {
                IntValue     = -1,
                FloatValue   = -1,
                DoubleValue  = -1,
                DecimalValue = -1m
            };

            // Act:
            var validationErrors = numberValidator.Validate(toValidate);

            // Assert:
            validationErrors.Count.Should().Be(4);
            foreach (var validationError in validationErrors)
            {
                validationError.ErrorMessage.Should().Be("Value must be greater than or equal to 0");
                validationError.ErrorCode.Should().Be("NUM_LESS_THAN");
                validationError.PropertyPath.IsEmpty.Should().BeFalse();
                validationError.ProvidedValue.Should().Be(-1);
            }
        }
Ejemplo n.º 8
0
        public void AddVariable(string varName, string value)
        {
            var nc = new NumberClass {
                NumberType = NumberClass.NumberTypes.Expression, Expression = value
            };

            AddVariable(varName, nc);
        }
Ejemplo n.º 9
0
        public void AddVariable(string varName, double value)
        {
            var nc = new NumberClass {
                NumberType = NumberClass.NumberTypes.Float, FloatNumber = value
            };

            AddVariable(varName, nc);
        }
Ejemplo n.º 10
0
        public void AddVariable(string varName, int value)
        {
            var nc = new NumberClass {
                NumberType = NumberClass.NumberTypes.Integer, IntNumber = value
            };

            AddVariable(varName, nc);
        }
Ejemplo n.º 11
0
 private void EvaluateFunction(NumberClass expression, FunctionClass fc)
 {
     EvaluateFunction(expression, fc, new List <NumberClass> {
         new NumberClass {
             NumberType = NumberClass.NumberTypes.Integer, IntNumber = 0
         }
     });
 }
Ejemplo n.º 12
0
        public void PlusPlus()
        {
            NumberClass n = 1;

            Assert.True(n == 1);
            n++;
            Assert.True(n == 2 && ++n == 3);
        }
        public void FindNextBiggerNumber_10_minus1return()
        {
            int         expected    = -1;
            NumberClass numberClass = new NumberClass();
            int         actual      = numberClass.FindNextBiggerNumber(10);

            Assert.AreEqual(expected, actual);
        }
Ejemplo n.º 14
0
        public void AddTest()
        {
            Assert.True(n1 + n2 == new NumberClass(1, 50));
            var preAdd = new NumberClass("1e30") + "6e29";
            var addRes = new NumberClass(1.6f, 30);

            Assert.True(preAdd == addRes);
        }
        public void FindNextBiggerNumber_144_414return()
        {
            int         expected    = 414;
            NumberClass numberClass = new NumberClass();
            int         actual      = numberClass.FindNextBiggerNumber(144);

            Assert.AreEqual(expected, actual);
        }
        public void FindNextBiggerNumber_3456432_3462345return()
        {
            int         expected    = 3462345;
            NumberClass numberClass = new NumberClass();
            int         actual      = numberClass.FindNextBiggerNumber(3456432);

            Assert.AreEqual(expected, actual);
        }
        public void FindNextBiggerNumber_2017_2071return()
        {
            int         expected    = 2071;
            NumberClass numberClass = new NumberClass();
            int         actual      = numberClass.FindNextBiggerNumber(2017);

            Assert.AreEqual(expected, actual);
        }
        public void FindNextBiggerNumber_513_531return()
        {
            int         expected    = 531;
            NumberClass numberClass = new NumberClass();
            int         actual      = numberClass.FindNextBiggerNumber(513);

            Assert.AreEqual(expected, actual);
        }
        public void InsertNumber_15_15_0_0_15return()
        {
            int         expected    = 15;
            NumberClass numberClass = new NumberClass();
            int         actual      = numberClass.InsertNumber(15, 15, 0, 0);

            Assert.AreEqual(expected, actual);
        }
        public void InsertNumber_8_15_3_8_120return()
        {
            int         expected    = 120;
            NumberClass numberClass = new NumberClass();
            int         actual      = numberClass.InsertNumber(8, 15, 3, 8);

            Assert.AreEqual(expected, actual);
        }
        public void FindNthRoot_8_3_point0001_2return()
        {
            double      expected    = 2;
            double      accuracy    = 0.0001;
            NumberClass numberClass = new NumberClass();
            double      actual      = numberClass.FindNthRoot(8, 3, accuracy);

            Assert.AreEqual(expected, actual, accuracy);
        }
Ejemplo n.º 22
0
        public void AddFunction(string functionName, FunctionArgumentList argList, string expression)
        {
            var fc = new FunctionClass { Arguments = argList, Expression = expression, Name = functionName };
            var numClass = new NumberClass { NumberType = NumberClass.NumberTypes.Expression, Expression = expression };

            EvaluateFunction(numClass, fc);

            _functions.Add(fc);
        }
        public void FindNthRoot_1_5_point0001_1return()
        {
            double      expected    = 1;
            double      accuracy    = 0.0001;
            NumberClass numberClass = new NumberClass();
            double      actual      = numberClass.FindNthRoot(1, 5, accuracy);

            Assert.AreEqual(expected, actual, accuracy);
        }
        public void FindNthRoot_point004241979_9_point00000001_point545return()
        {
            double      expected    = 0.545;
            double      accuracy    = 0.00000001;
            NumberClass numberClass = new NumberClass();
            double      actual      = numberClass.FindNthRoot(0.004241979, 9, accuracy);

            Assert.AreEqual(expected, actual, accuracy);
        }
Ejemplo n.º 25
0
 protected void Page_Load(object sender, EventArgs e)
 {
     if (!IsPostBack)
     {
         lbtDeleteT.Attributes.Add("onClick", "javascript:return confirm('Bạn có muốn xóa?');");
         lbtDeleteB.Attributes.Add("onClick", "javascript:return confirm('Bạn có muốn xóa?');");
         NumberClass.OnlyInputNumber(txtOrd);
         BindGrid();
     }
 }
Ejemplo n.º 26
0
 protected void Page_Load(object sender, EventArgs e)
 {
     if (!IsPostBack)
     {
         lbtDeleteT.Attributes.Add("onClick", "javascript:return confirm('Bạn có muốn xóa?');");
         lbtDeleteB.Attributes.Add("onClick", "javascript:return confirm('Bạn có muốn xóa?');");
         NumberClass.OnlyInputNumber(txtOrd);
         BindGrid();
         LoadDropDownListGroupImage();
         //PageHelper.LoadDropProPriority(ddlPriority);
     }
 }
Ejemplo n.º 27
0
        public void Does_use_invariant_culture_for_numbers()
        {
            var dto = NumberClass.Create(1);

            dto.ToJson().Print();
            dto.ToJsv().Print();
            dto.ToCsv().Print();

            Assert.That(dto.ToJson(), Does.Not.Contain("1000,9"));
            Assert.That(dto.ToJsv(), Does.Not.Contain("1000,9"));
            Assert.That(dto.ToCsv(), Does.Not.Contain("1000,9"));
        }
Ejemplo n.º 28
0
        public static object Multiply(object first, object second)
        {
            NumberClass f = GetNumberClass(first);

            if (f == NumberClass.NotANumber)
            {
                throw new NotSupportedException("number type not supported");
            }

            NumberClass s = GetNumberClass(second);

            if (s == NumberClass.NotANumber)
            {
                throw new NotSupportedException("number type not supported");
            }

            NumberClass effective = f & s;

            switch (effective)
            {
            case NumberClass.Integer:
            {
                long result = (long)ConvertToInteger(first) * ConvertToInteger(second);
                if (result > int.MaxValue || result < int.MinValue)
                {
                    return((BigInteger)result);
                }
                else
                {
                    return(RuntimeHelpers.Int32ToObject((int)result));
                }
            }

            case NumberClass.BigInteger:
                return(ToIntegerIfPossible(ConvertToBigInteger(first) * ConvertToBigInteger(second)));

            case NumberClass.Rational:
                return(IntegerIfPossible(ConvertToRational(first) * ConvertToRational(second)));

            case NumberClass.Real:
                return(ConvertToReal(first) * ConvertToReal(second));

            case NumberClass.Complex:
                if (IsExact(first) && IsExact(second))
                {
                    return(IntegerIfPossible(ConvertToComplexFraction(first) * ConvertToComplexFraction(second)));
                }
                return(DoubleIfPossible(ConvertToComplex(first) * ConvertToComplex(second)));
            }

            throw new NotSupportedException("number type not supported");
        }
Ejemplo n.º 29
0
        public void AddFunction(string functionName, FunctionArgumentList argList, string expression)
        {
            var fc = new FunctionClass {
                Arguments = argList, Expression = expression, Name = functionName
            };
            var numClass = new NumberClass {
                NumberType = NumberClass.NumberTypes.Expression, Expression = expression
            };

            EvaluateFunction(numClass, fc);

            _functions.Add(fc);
        }
Ejemplo n.º 30
0
 public void 当输入整数小于1000000大于等于1000测试()
 {
     Assert.AreEqual(NumberClass.NumberName(6235000), "six million and two hundred and thirty five thousand");
     Assert.AreEqual(NumberClass.NumberName(6235123), "six million and two hundred and thirty five thousand and one hundred and twenty three");
     Assert.AreEqual(NumberClass.NumberName(236235123), "two hundred and thirty six million and two hundred and thirty five thousand and one hundred and twenty three");
     Assert.AreEqual(NumberClass.NumberName(6235000), "six million and two hundred and thirty five thousand");
     Assert.AreEqual(NumberClass.NumberName(6235123), "six million and two hundred and thirty five thousand and one hundred and twenty three");
     Assert.AreEqual(NumberClass.NumberName(1236235123), "one billion and two hundred and thirty six million and two hundred and thirty five thousand and one hundred and twenty three");
     Assert.AreEqual(NumberClass.NumberName(21236235123), "twenty one billion and two hundred and thirty six million and two hundred and thirty five thousand and one hundred and twenty three");
     Assert.AreEqual(NumberClass.NumberName(321236235123), "three hundred and twenty one billion and two hundred and thirty six million and two hundred and thirty five thousand and one hundred and twenty three");
     Assert.AreEqual(NumberClass.NumberName(1321236235123), "one trillion and three hundred and twenty one billion and two hundred and thirty six million and two hundred and thirty five thousand and one hundred and twenty three");
     Assert.AreEqual(NumberClass.NumberName(21321236235123), "twenty one trillion and three hundred and twenty one billion and two hundred and thirty six million and two hundred and thirty five thousand and one hundred and twenty three");
     Assert.AreEqual(NumberClass.NumberName(321321236235123), "three hundred and twenty one trillion and three hundred and twenty one billion and two hundred and thirty six million and two hundred and thirty five thousand and one hundred and twenty three");
 }
        public void FilterDigit_8()
        {
            List <int> initialList = new List <int>()
            {
                1, 17, 45, 65, 76, 725, 3, 9, 7, 37
            };
            List <int> expected = new List <int>()
            {
            };
            NumberClass numberClass = new NumberClass();
            List <int>  actual      = numberClass.FilterDigit(initialList, 8);

            CollectionAssert.AreEqual(expected, actual);
        }
Ejemplo n.º 32
0
        public SimplificationReturnValue Simplify(string equation)
        {
            var retval = new SimplificationReturnValue { OriginalEquation = equation };
            validateExpression(equation);
            if (equation.Trim().StartsWith("-") || equation.Trim().StartsWith("+"))
                equation = "0" + equation;
            equation = equation.Replace("(+", "(0+");
            equation = equation.Replace("(-", "(0-");
            equation = equation.Replace("( +", "( 0+");
            equation = equation.Replace("( -", "( 0-");
            equation = equation.Replace(",-", ",0-");
            equation = equation.Replace(", -", ", 0-");
            equation = equation.Replace(",+", ",0+");
            equation = equation.Replace(", +", ", 0+");

            var tp = new TokenParser();

            foreach (var cf in _customFunctions)
            {
                tp.RegisterCustomFunction(cf.Key);
            }

            tp.InputString = equation;

            Token token = tp.GetToken();

            _operatorStack.Clear();
            _outputQueue.Clear();

            #region Filling _outputQueue
            while (token != null)
            {
                #region Sqare Root Token
                if (token.TokenName == TokenParser.Tokens.Sqrt)
                {
                    string expression = token.TokenValue.Substring(4, token.TokenValue.Length - 4);

                    SimplificationReturnValue rv = EvaluateExpression(new NumberClass
                                                                          {
                                                                              Expression = expression,
                                                                              NumberType = NumberClass.NumberTypes.Expression
                                                                          });

                    token.TokenName = TokenParser.Tokens.Float;

                    switch (rv.ReturnType)
                    {
                        case SimplificationReturnValue.ReturnTypes.Integer:
                            token.TokenValue = Math.Sqrt(rv.IntValue).ToString();
                            break;
                        case SimplificationReturnValue.ReturnTypes.Float:
                            token.TokenValue = Math.Sqrt(rv.DoubleValue).ToString();
                            break;
                    }
                }
                #endregion

                #region Sinus Token
                if (token.TokenName == TokenParser.Tokens.Sin)
                {
                    string expression = token.TokenValue.Substring(3, token.TokenValue.Length - 3);

                    SimplificationReturnValue rv =
                        EvaluateExpression(new NumberClass
                        {
                            Expression = expression,
                            NumberType = NumberClass.NumberTypes.Expression
                        });

                    token.TokenName = TokenParser.Tokens.Float;

                    switch (rv.ReturnType)
                    {
                        case SimplificationReturnValue.ReturnTypes.Integer:
                            token.TokenValue = Math.Sin(rv.IntValue).ToString();
                            break;
                        case SimplificationReturnValue.ReturnTypes.Float:
                            token.TokenValue = Math.Sin(rv.DoubleValue).ToString();
                            break;
                    }
                }
                #endregion

                #region Log Token
                if (token.TokenName == TokenParser.Tokens.Log)
                {
                    string expression = token.TokenValue.Substring(3, token.TokenValue.Length - 3);

                    SimplificationReturnValue rv =
                        EvaluateExpression(new NumberClass
                        {
                            Expression = expression,
                            NumberType = NumberClass.NumberTypes.Expression
                        });

                    token.TokenName = TokenParser.Tokens.Float;

                    switch (rv.ReturnType)
                    {
                        case SimplificationReturnValue.ReturnTypes.Integer:
                            token.TokenValue = Math.Log(rv.IntValue, 10).ToString();
                            break;
                        case SimplificationReturnValue.ReturnTypes.Float:
                            token.TokenValue = Math.Log(rv.DoubleValue, 10).ToString();
                            break;
                    }
                }
                #endregion

                #region Log Natural Token
                if (token.TokenName == TokenParser.Tokens.LogN)
                {
                    string expression = token.TokenValue.Substring(4, token.TokenValue.Length - 4);

                    SimplificationReturnValue rv =
                        EvaluateExpression(new NumberClass
                        {
                            Expression = expression,
                            NumberType = NumberClass.NumberTypes.Expression
                        });

                    token.TokenName = TokenParser.Tokens.Float;

                    switch (rv.ReturnType)
                    {
                        case SimplificationReturnValue.ReturnTypes.Integer:
                            token.TokenValue = Math.Log(rv.IntValue).ToString();
                            break;
                        case SimplificationReturnValue.ReturnTypes.Float:
                            token.TokenValue = Math.Log(rv.DoubleValue).ToString();
                            break;
                    }
                }
                #endregion

                #region Tangens Token
                if (token.TokenName == TokenParser.Tokens.Tan)
                {
                    string expression = token.TokenValue.Substring(3, token.TokenValue.Length - 3);

                    var rv =
                        EvaluateExpression(new NumberClass
                        {
                            Expression = expression,
                            NumberType = NumberClass.NumberTypes.Expression
                        });

                    token.TokenName = TokenParser.Tokens.Float;

                    switch (rv.ReturnType)
                    {
                        case SimplificationReturnValue.ReturnTypes.Integer:
                            token.TokenValue = Math.Tan(rv.IntValue).ToString();
                            break;
                        case SimplificationReturnValue.ReturnTypes.Float:
                            token.TokenValue = Math.Tan(rv.DoubleValue).ToString();
                            break;
                    }
                }
                #endregion

                #region Absulute Value Token
                if (token.TokenName == TokenParser.Tokens.Abs)
                {
                    string expression = token.TokenValue.Substring(3, token.TokenValue.Length - 3);

                    var rv =
                        EvaluateExpression(new NumberClass
                        {
                            Expression = expression,
                            NumberType = NumberClass.NumberTypes.Expression
                        });

                    token.TokenName = TokenParser.Tokens.Float;

                    switch (rv.ReturnType)
                    {
                        case SimplificationReturnValue.ReturnTypes.Integer:
                            token.TokenValue = Math.Abs(rv.IntValue).ToString();
                            break;
                        case SimplificationReturnValue.ReturnTypes.Float:
                            token.TokenValue = Math.Abs(rv.DoubleValue).ToString();
                            break;
                    }
                }
                #endregion

                #region Cosinus Token
                if (token.TokenName == TokenParser.Tokens.Cos)
                {
                    string expression = token.TokenValue.Substring(3, token.TokenValue.Length - 3);

                    var rv =
                        EvaluateExpression(new NumberClass
                        {
                            Expression = expression,
                            NumberType = NumberClass.NumberTypes.Expression
                        });

                    token.TokenName = TokenParser.Tokens.Float;

                    switch (rv.ReturnType)
                    {
                        case SimplificationReturnValue.ReturnTypes.Integer:
                            token.TokenValue = Math.Cos(rv.IntValue).ToString();
                            break;
                        case SimplificationReturnValue.ReturnTypes.Float:
                            token.TokenValue = Math.Cos(rv.DoubleValue).ToString();
                            break;
                    }
                }
                #endregion

                #region Unknown Token
                if ((int)token.TokenName >= 100)
                {
                    int ndx1 = token.TokenValue.IndexOf("(");
                    string fn = token.TokenValue.Substring(0, ndx1);
                    string origExpression = token.TokenValue.Substring(ndx1);
                    string[] expressions = origExpression.Replace(",", "),(").Split(',');
                    bool found = false;

                    if (_customFunctions.Any(c => c.Key.Equals(fn)))
                        found = true;

                    if (found)
                    {
                        foreach (var ff in _customFunctions)
                        {
                            if (ff.Key.Equals(fn))
                            {
                                var p = new Parser();
                                foreach (var cfr in _customFunctions)
                                    p.AddCustomFunction(cfr.Key, cfr.Value);
                                foreach (var vr in _variables)
                                    p.AddVariable(vr.Key, vr.Value);
                                foreach (var vf in _functions)
                                    p.AddFunction(vf.Name, vf.Arguments, vf.Expression);

                                var ex = expressions.Select(p.Simplify).ToArray();

                                object funcRetval = null;

                                if (ff.Value.Method.ReturnType == typeof(int))
                                {
                                    var intParams = new object[ex.Length];
                                    int ndx = 0;

                                    foreach (var pp in ex)
                                    {
                                        if (pp.ReturnType == SimplificationReturnValue.ReturnTypes.Float)
                                            intParams[ndx] = (int)pp.DoubleValue;
                                        if (pp.ReturnType == SimplificationReturnValue.ReturnTypes.Integer)
                                            intParams[ndx] = pp.IntValue;
                                        ndx++;
                                    }
                                    funcRetval = ff.Value.DynamicInvoke(intParams);
                                }
                                if (ff.Value.Method.ReturnType == typeof(double))
                                {
                                    var floatParams = new object[ex.Length];
                                    int ndx = 0;

                                    foreach (var pp in ex)
                                    {
                                        if (pp.ReturnType == SimplificationReturnValue.ReturnTypes.Float)
                                            floatParams[ndx] = pp.DoubleValue;
                                        if (pp.ReturnType == SimplificationReturnValue.ReturnTypes.Integer)
                                            floatParams[ndx] = pp.IntValue;
                                        ndx++;
                                    }
                                    funcRetval = ff.Value.DynamicInvoke(floatParams);
                                }
                                if (ff.Value.Method.ReturnType==typeof(object))
                                {
                                    funcRetval = ff.Value.DynamicInvoke(expressions.Select(p.Simplify).ToArray());
                                }

                                //object funcRetval = ff.Value.DynamicInvoke(expressions.Select(p.Simplify).ToArray());

                                if (funcRetval is double)
                                {
                                    token.TokenValue = ((double)funcRetval).ToString();
                                    token.TokenName = TokenParser.Tokens.Float;
                                }
                                if (funcRetval is int)
                                {
                                    token.TokenValue = ((int)funcRetval).ToString();
                                    token.TokenName = TokenParser.Tokens.Integer;
                                }
                                if (funcRetval is SimplificationReturnValue)
                                {
                                    var srv = (SimplificationReturnValue)funcRetval;
                                    if (srv.ReturnType == SimplificationReturnValue.ReturnTypes.Integer)
                                    {
                                        token.TokenValue = srv.IntValue.ToString();
                                        token.TokenName = TokenParser.Tokens.Integer;
                                    }
                                    if (srv.ReturnType == SimplificationReturnValue.ReturnTypes.Float)
                                    {
                                        token.TokenValue = srv.DoubleValue.ToString();
                                        token.TokenName = TokenParser.Tokens.Float;
                                    }
                                }
                                break;
                            }
                        }
                    }

                    if (!found)
                    {
                        throw new NoSuchFunctionException();//StringResources.No_such_function_defined + ": " + fn);
                    }
                }
                #endregion

                #region Function Token
                if (token.TokenName == TokenParser.Tokens.Function)
                {
                    int ndx1 = token.TokenValue.IndexOf("(");
                    string fn = token.TokenValue.Substring(0, ndx1).Remove(0, 4);
                    string origExpression = token.TokenValue.Substring(ndx1);
                    string[] expressions = origExpression.Replace(",", "),(").Split(',');
                    bool found = false;
                    FunctionClass fun = null;

                    if (_functions.Any(c => c.Name.Equals(fn)))
                    {
                        found = true;
                    }

                    if (found)
                    {
                        foreach (var ff in _functions)
                            if (ff.Name.Equals(fn))
                                fun = ff;
                    }

                    if (!found)
                    {
                        throw new NoSuchFunctionException();//StringResources.No_such_function_defined + ": " + fn);
                    }

                    var parser = new Parser();
                    foreach (var cfh in _customFunctions)
                        parser.AddCustomFunction(cfh.Key, cfh.Value);

                    foreach (var v in _variables)
                    {
                        if (v.Value.NumberType == NumberClass.NumberTypes.Float)
                        {
                            parser.AddVariable(v.Key, v.Value.FloatNumber);
                        }
                        if (v.Value.NumberType == NumberClass.NumberTypes.Integer)
                        {
                            parser.AddVariable(v.Key, v.Value.IntNumber);
                        }
                        if (v.Value.NumberType == NumberClass.NumberTypes.Expression)
                        {
                            parser.AddVariable(v.Key, v.Value.Expression);
                        }
                    }

                    foreach (var f in _functions)
                    {
                        parser.AddFunction(f.Name, f.Arguments, f.Expression);
                    }
                    var expressionList = new List<NumberClass>();

                    foreach (var expression in expressions)
                    {
                        SimplificationReturnValue simRetval = parser.Simplify(expression);

                        var numClass = new NumberClass();
                        if (simRetval.ReturnType == SimplificationReturnValue.ReturnTypes.Float)
                        {
                            numClass.FloatNumber = simRetval.DoubleValue;
                            numClass.NumberType = NumberClass.NumberTypes.Float;
                        }
                        if (simRetval.ReturnType == SimplificationReturnValue.ReturnTypes.Integer)
                        {
                            numClass.IntNumber = simRetval.IntValue;
                            numClass.NumberType = NumberClass.NumberTypes.Integer;
                        }
                        expressionList.Add(numClass);
                    }

                    if (fun != null)
                    {
                        var numClass = new NumberClass { NumberType = NumberClass.NumberTypes.Expression, Expression = fun.Expression };

                        SimplificationReturnValue sretval = parser.EvaluateFunction(numClass, fun, expressionList);

                        if (sretval != null && sretval.ReturnType == SimplificationReturnValue.ReturnTypes.Integer)
                        {
                            token.TokenName = TokenParser.Tokens.Integer;
                            token.TokenValue = sretval.IntValue.ToString();
                        }
                        if (sretval != null && sretval.ReturnType == SimplificationReturnValue.ReturnTypes.Float)
                        {
                            token.TokenName = TokenParser.Tokens.Float;
                            token.TokenValue = sretval.DoubleValue.ToString();
                        }
                    }
                }
                #endregion

                #region Variable Token
                if (token.TokenName == TokenParser.Tokens.Variable)
                {
                    if (_variables.ContainsKey(token.TokenValue))
                    {
                        var z = _variables[token.TokenValue];

                        if (z.NumberType == NumberClass.NumberTypes.Float)
                        {
                            token.TokenName = TokenParser.Tokens.Float;
                            token.TokenValue = z.FloatNumber.ToString();
                        }
                        else if (z.NumberType == NumberClass.NumberTypes.Integer)
                        {
                            token.TokenName = TokenParser.Tokens.Integer;
                            token.TokenValue = z.IntNumber.ToString();
                        }
                    }
                    else
                    {
                        throw new NoSuchVariableException();//StringResources.Undefined_Variable + ": " + token.TokenValue);
                    }
                }
                #endregion

                #region White space or NewLine Token
                if (token.TokenName == TokenParser.Tokens.Whitespace || token.TokenName == TokenParser.Tokens.Newline)
                {
                    token = tp.GetToken();
                    continue;
                }
                #endregion

                #region Integer or Float token
                if (token.TokenName == TokenParser.Tokens.Integer || token.TokenName == TokenParser.Tokens.Float)
                {
                    var nc = new NumberClass();

                    switch (token.TokenName)
                    {
                        case TokenParser.Tokens.Float:
                            nc.NumberType = NumberClass.NumberTypes.Float;
                            nc.FloatNumber = double.Parse(token.TokenValue.Replace('.', ','));
                            break;
                        case TokenParser.Tokens.Integer:
                            nc.NumberType = NumberClass.NumberTypes.Integer;
                            nc.IntNumber = int.Parse(token.TokenValue);
                            break;
                    }
                    _outputQueue.Enqueue(nc);
                }
                #endregion

                #region IsOperator Token
                if (IsOperator(token.TokenName))
                {
                    if (_operatorStack.Count > 0)
                    {
                        while (_operatorStack.Count > 0)
                        {
                            var op = _operatorStack.Peek(); //o2

                            if (op == "(" || op == ")")
                                break;
                            if ((GetPrecedence(token.TokenName) <= GetPrecedence(op) &&
                                 IsLeftAssociative(token.TokenValue)) ||
                                !IsLeftAssociative(token.TokenValue) &&
                                GetPrecedence(token.TokenName) < GetPrecedence(op))
                            {
                                op = _operatorStack.Pop();
                                var nc = new NumberClass { NumberType = NumberClass.NumberTypes.Operator, Operator = op };

                                _outputQueue.Enqueue(nc);
                            }
                            else break;
                        }
                    }
                    _operatorStack.Push(token.TokenValue);
                }
                #endregion

                #region Lparen Token
                if (token.TokenName == TokenParser.Tokens.Lparen)
                    _operatorStack.Push(token.TokenValue);
                #endregion

                #region Rparen Token
                if (token.TokenName == TokenParser.Tokens.Rparen)
                {
                    if (_operatorStack.Count > 0)
                    {
                        var op = _operatorStack.Pop();

                        while (op != "(")
                        {
                            var nc = new NumberClass { Operator = op, NumberType = NumberClass.NumberTypes.Operator };

                            _outputQueue.Enqueue(nc);

                            if (_operatorStack.Count > 0)
                                op = _operatorStack.Pop();
                            else
                            {
                                throw new MismatchedParenthesisException();
                            }
                        }
                    }
                    else
                    {
                        throw new MismatchedParenthesisException();
                    }
                }
                #endregion

                token = tp.GetToken();
            }

            #endregion

            while (_operatorStack.Count > 0)
            {
                var op = _operatorStack.Pop();

                if (op == "(" || op == ")")
                {
                    throw new MismatchedParenthesisException();
                }

                var nc = new NumberClass { NumberType = NumberClass.NumberTypes.Operator, Operator = op };

                _outputQueue.Enqueue(nc);
            }

            bool floatAnswer = true;// _outputQueue.Any(v => v.NumberType == NumberClass.NumberTypes.Float);
            var intStack = new Stack<int>();
            int lastMemoryCell = 0;
            /*
             * Clearing stack before use it;
             */
            try
            {
                _pbStack.clearStack();
                if (floatAnswer || _outputQueue.Any(v => v.Operator == "/"))
                {
                    //var dblStack = new Stack<double>();

                    // Type{integer,float,operator, memory},{value/mem index}
                    var newStack = new Stack<StackData>();
                    String leftOperand, rightOperand;
                    int leftOperandInt, rightOperandInt;
                    foreach (var nc in _outputQueue)
                    {
                        if (nc.NumberType == NumberClass.NumberTypes.Integer)
                        {
                            newStack.Push(new StackData("int", nc.IntNumber));
                            continue;
                        }

                        if (nc.NumberType == NumberClass.NumberTypes.Float)
                        {
                            newStack.Push(new StackData("float", nc.FloatNumber));
                            continue;
                        }

                        if (nc.NumberType == NumberClass.NumberTypes.Operator)
                        {

                            // Stack filling
                            // if left operand aren't memory cell and right aren't memory cell
                            if ((newStack.Peek().dataType != "mem") && (newStack.ElementAt(1).dataType != "mem"))
                            {
                                rightOperand = newStack.Pop().dataValue.ToString();
                                leftOperand = newStack.Pop().dataValue.ToString();

                                _pbStack.PushCommand(nc.Operator, leftOperand, rightOperand);
                            }
                            else
                            {
                                // if left operand stored in memory
                                if (newStack.Peek().dataType == "mem")
                                {
                                    if (newStack.ElementAt(1).dataType != "mem")
                                    {
                                        leftOperandInt = (int)newStack.Pop().dataValue;
                                        rightOperand = newStack.Pop().dataValue.ToString();

                                        // use push with memory index for left operand
                                        _pbStack.PushCommand(nc.Operator, leftOperandInt, rightOperand);
                                    }
                                    else
                                    {
                                        leftOperandInt = (int)newStack.Pop().dataValue;
                                        rightOperandInt = (int)newStack.Pop().dataValue;
                                        // use push with memory index for left operand
                                        // TODO: Implement Push Command for KOP MEM MEM
                                        _pbStack.PushCommand(nc.Operator, leftOperandInt, rightOperandInt);
                                    }
                                }
                                else
                                {
                                    /* If right operand stored in memory */
                                    // Get left operand value
                                    leftOperand = newStack.Pop().dataValue.ToString();

                                    // Get right operand memory index
                                    rightOperandInt = (int)newStack.Pop().dataValue;

                                    // Use push with memory index for right operand
                                    _pbStack.PushCommand(nc.Operator, leftOperand, rightOperandInt);
                                }
                            }
                            //double val = DoMath(nc.Operator, dblStack.Pop(), dblStack.Pop());

                            lastMemoryCell = _pbStack.PeekCommand().MemoryCellUsed;
                            //dblStack.Push(-lastMemoryCell - 1);
                            newStack.Push(new StackData("mem", lastMemoryCell));
                        }
                    }

                    if (newStack.Count == 0)
                    {
                        throw new CouldNotParseExpressionException();
                    }
                    retval.DoubleValue = newStack.Pop().dataValue;
                    retval.ReturnType = SimplificationReturnValue.ReturnTypes.Float;
                }
                else
                {

                    foreach (var nc in _outputQueue)
                    {
                        if (nc.NumberType == NumberClass.NumberTypes.Integer)
                            intStack.Push(nc.IntNumber);
                        if (nc.NumberType == NumberClass.NumberTypes.Float)
                            intStack.Push((int)nc.FloatNumber);
                        if (nc.NumberType == NumberClass.NumberTypes.Operator)
                        {
                            // Stack filling
                            if (intStack.Count == 2)
                                _pbStack.PushCommand(nc.Operator, intStack.Pop().ToString(), intStack.Pop().ToString());
                            else
                                if (intStack.Count == 1)
                                    _pbStack.PushCommand(nc.Operator, intStack.Pop().ToString(), lastMemoryCell);
                            // Delete this and add stack filling
                            //int val = DoMath(nc.Operator, intStack.Pop(), intStack.Pop());
                            lastMemoryCell = _pbStack.PeekCommand().MemoryCellUsed;
                            //intStack.Push(val);
                        }
                    }

                    if (intStack.Count == 0)
                    {
                        throw new CouldNotParseExpressionException();
                    }
                    retval.IntValue = intStack.Pop();
                    retval.ReturnType = SimplificationReturnValue.ReturnTypes.Integer;
                }
            }
            catch (Exception ex)
            {
                return null;
            }

            return retval;
        }
Ejemplo n.º 33
0
        public SimplificationReturnValue Simplify(string equation)
        {
            var retval = new SimplificationReturnValue { OriginalEquation = equation };

            if (equation.Trim().StartsWith("-") || equation.Trim().StartsWith("+"))
                equation = "0" + equation;
            equation = equation.Replace("(+", "(0+");
            equation = equation.Replace("(-", "(0-");
            equation = equation.Replace("( +", "( 0+");
            equation = equation.Replace("( -", "( 0-");
            equation = equation.Replace(",-", ",0-");
            equation = equation.Replace(", -", ", 0-");
            equation = equation.Replace(",+", ",0+");
            equation = equation.Replace(", +", ", 0+");

            var tp = new TokenParser();

            foreach (var cf in _customFunctions)
            {
                tp.RegisterCustomFunction(cf.Key);
            }

            tp.InputString = equation;

            Token token = tp.GetToken();

            _operatorStack.Clear();
            _outputQueue.Clear();

            while (token != null)
            {
                if (token.TokenName == TokenParser.Tokens.Sqrt)
                {
                    string expression = token.TokenValue.Substring(4, token.TokenValue.Length - 4);

                    SimplificationReturnValue rv = EvaluateExpression(new NumberClass
                                                                          {
                                                                              Expression = expression,
                                                                              NumberType = NumberClass.NumberTypes.Expression
                                                                          });

                    token.TokenName = TokenParser.Tokens.Float;

                    switch (rv.ReturnType)
                    {
                        case SimplificationReturnValue.ReturnTypes.Integer:
                            token.TokenValue = Math.Sqrt(rv.IntValue).ToString();
                            break;
                        case SimplificationReturnValue.ReturnTypes.Float:
                            token.TokenValue = Math.Sqrt(rv.DoubleValue).ToString();
                            break;
                    }
                }
                if (token.TokenName == TokenParser.Tokens.Sin)
                {
                    string expression = token.TokenValue.Substring(3, token.TokenValue.Length - 3);

                    SimplificationReturnValue rv =
                        EvaluateExpression(new NumberClass
                        {
                            Expression = expression,
                            NumberType = NumberClass.NumberTypes.Expression
                        });

                    token.TokenName = TokenParser.Tokens.Float;

                    switch (rv.ReturnType)
                    {
                        case SimplificationReturnValue.ReturnTypes.Integer:
                            token.TokenValue = Math.Sin(rv.IntValue).ToString();
                            break;
                        case SimplificationReturnValue.ReturnTypes.Float:
                            token.TokenValue = Math.Sin(rv.DoubleValue).ToString();
                            break;
                    }
                }
                if (token.TokenName == TokenParser.Tokens.Log)
                {
                    string expression = token.TokenValue.Substring(3, token.TokenValue.Length - 3);

                    SimplificationReturnValue rv =
                        EvaluateExpression(new NumberClass
                        {
                            Expression = expression,
                            NumberType = NumberClass.NumberTypes.Expression
                        });

                    token.TokenName = TokenParser.Tokens.Float;

                    switch (rv.ReturnType)
                    {
                        case SimplificationReturnValue.ReturnTypes.Integer:
                            token.TokenValue = Math.Log(rv.IntValue, 10).ToString();
                            break;
                        case SimplificationReturnValue.ReturnTypes.Float:
                            token.TokenValue = Math.Log(rv.DoubleValue, 10).ToString();
                            break;
                    }
                }
                if (token.TokenName == TokenParser.Tokens.LogN)
                {
                    string expression = token.TokenValue.Substring(4, token.TokenValue.Length - 4);

                    SimplificationReturnValue rv =
                        EvaluateExpression(new NumberClass
                        {
                            Expression = expression,
                            NumberType = NumberClass.NumberTypes.Expression
                        });

                    token.TokenName = TokenParser.Tokens.Float;

                    switch (rv.ReturnType)
                    {
                        case SimplificationReturnValue.ReturnTypes.Integer:
                            token.TokenValue = Math.Log(rv.IntValue).ToString();
                            break;
                        case SimplificationReturnValue.ReturnTypes.Float:
                            token.TokenValue = Math.Log(rv.DoubleValue).ToString();
                            break;
                    }
                }
                if (token.TokenName == TokenParser.Tokens.Tan)
                {
                    string expression = token.TokenValue.Substring(3, token.TokenValue.Length - 3);

                    var rv =
                        EvaluateExpression(new NumberClass
                        {
                            Expression = expression,
                            NumberType = NumberClass.NumberTypes.Expression
                        });

                    token.TokenName = TokenParser.Tokens.Float;

                    switch (rv.ReturnType)
                    {
                        case SimplificationReturnValue.ReturnTypes.Integer:
                            token.TokenValue = Math.Tan(rv.IntValue).ToString();
                            break;
                        case SimplificationReturnValue.ReturnTypes.Float:
                            token.TokenValue = Math.Tan(rv.DoubleValue).ToString();
                            break;
                    }
                }
                if (token.TokenName == TokenParser.Tokens.Abs)
                {
                    string expression = token.TokenValue.Substring(3, token.TokenValue.Length - 3);

                    var rv =
                        EvaluateExpression(new NumberClass
                        {
                            Expression = expression,
                            NumberType = NumberClass.NumberTypes.Expression
                        });

                    token.TokenName = TokenParser.Tokens.Float;

                    switch (rv.ReturnType)
                    {
                        case SimplificationReturnValue.ReturnTypes.Integer:
                            token.TokenValue = Math.Abs(rv.IntValue).ToString();
                            break;
                        case SimplificationReturnValue.ReturnTypes.Float:
                            token.TokenValue = Math.Abs(rv.DoubleValue).ToString();
                            break;
                    }
                }
                if (token.TokenName == TokenParser.Tokens.Cos)
                {
                    string expression = token.TokenValue.Substring(3, token.TokenValue.Length - 3);

                    var rv =
                        EvaluateExpression(new NumberClass
                        {
                            Expression = expression,
                            NumberType = NumberClass.NumberTypes.Expression
                        });

                    token.TokenName = TokenParser.Tokens.Float;

                    switch (rv.ReturnType)
                    {
                        case SimplificationReturnValue.ReturnTypes.Integer:
                            token.TokenValue = Math.Cos(rv.IntValue).ToString();
                            break;
                        case SimplificationReturnValue.ReturnTypes.Float:
                            token.TokenValue = Math.Cos(rv.DoubleValue).ToString();
                            break;
                    }
                }
                if ((int)token.TokenName >= 100)
                {
                    int ndx1 = token.TokenValue.IndexOf("(");
                    string fn = token.TokenValue.Substring(0, ndx1);
                    string origExpression = token.TokenValue.Substring(ndx1);
                    string[] expressions = origExpression.Replace(",", "),(").Split(',');
                    bool found = false;

                    foreach(var _f in _customFunctions)
                    {
                        if(_f.Key.Equals(fn))
                        {
                            found = true;
                            break;
                        }
                    }

                    if (found)
                    {
                        foreach (var ff in _customFunctions)
                        {
                            if (ff.Key.Equals(fn))
                            {
                                var p = new Parser();
                                foreach (var cfr in _customFunctions)
                                    p.AddCustomFunction(cfr.Key, cfr.Value);
                                foreach (var vr in _variables)
                                    p.AddVariable(vr.Key, vr.Value);
                                foreach (var vf in _functions)
                                    p.AddFunction(vf.Name, vf.Arguments, vf.Expression);

                                var ex = new SimplificationReturnValue[expressions.Length];

                                for(var i = 0; i < expressions.Length; i++)
                                {
                                    ex[i] = p.Simplify(expressions[i]);
                                }

                                object funcRetval = null;

                                if (ff.Value.Method.ReturnType == typeof(int))
                                {
                                    var intParams = new object[ex.Length];
                                    int ndx = 0;

                                    foreach (var pp in ex)
                                    {
                                        if (pp.ReturnType == SimplificationReturnValue.ReturnTypes.Float)
                                            intParams[ndx] = (int)pp.DoubleValue;
                                        if (pp.ReturnType == SimplificationReturnValue.ReturnTypes.Integer)
                                            intParams[ndx] = pp.IntValue;
                                        ndx++;
                                    }
                                    funcRetval = ff.Value.DynamicInvoke(intParams);
                                }
                                if (ff.Value.Method.ReturnType == typeof(double))
                                {
                                    var floatParams = new object[ex.Length];
                                    int ndx = 0;

                                    foreach (var pp in ex)
                                    {
                                        if (pp.ReturnType == SimplificationReturnValue.ReturnTypes.Float)
                                            floatParams[ndx] = pp.DoubleValue;
                                        if (pp.ReturnType == SimplificationReturnValue.ReturnTypes.Integer)
                                            floatParams[ndx] = pp.IntValue;
                                        ndx++;
                                    }
                                    funcRetval = ff.Value.DynamicInvoke(floatParams);
                                }
                                if (ff.Value.Method.ReturnType==typeof(object))
                                {
                                    var ex2 = new SimplificationReturnValue[expressions.Length];

                                    for(var i = 0; i < ex2.Length; i++)
                                        ex2[i] = p.Simplify(expressions[i]);

                                    funcRetval = ff.Value.DynamicInvoke(ex2);
                                }

                                //object funcRetval = ff.Value.DynamicInvoke(expressions.Select(p.Simplify).ToArray());

                                if (funcRetval is double)
                                {
                                    token.TokenValue = ((double)funcRetval).ToString();
                                    token.TokenName = TokenParser.Tokens.Float;
                                }
                                if (funcRetval is int)
                                {
                                    token.TokenValue = ((int)funcRetval).ToString();
                                    token.TokenName = TokenParser.Tokens.Integer;
                                }
                                if (funcRetval is SimplificationReturnValue)
                                {
                                    var srv = (SimplificationReturnValue)funcRetval;
                                    if (srv.ReturnType == SimplificationReturnValue.ReturnTypes.Integer)
                                    {
                                        token.TokenValue = srv.IntValue.ToString();
                                        token.TokenName = TokenParser.Tokens.Integer;
                                    }
                                    if (srv.ReturnType == SimplificationReturnValue.ReturnTypes.Float)
                                    {
                                        token.TokenValue = srv.DoubleValue.ToString();
                                        token.TokenName = TokenParser.Tokens.Float;
                                    }
                                }
                                break;
                            }
                        }
                    }

                    if (!found)
                    {
                        throw new NoSuchFunctionException(StringResources.No_such_function_defined + ": " + fn);
                    }
                }

                if (token.TokenName == TokenParser.Tokens.Function)
                {
                    int ndx1 = token.TokenValue.IndexOf("(");
                    string fn = token.TokenValue.Substring(0, ndx1).Remove(0, 4);
                    string origExpression = token.TokenValue.Substring(ndx1);
                    string[] expressions = origExpression.Replace(",", "),(").Split(',');
                    bool found = false;
                    FunctionClass fun = null;

                    foreach(var _f in _functions)
                    {
                        if(_f.Name.Equals(fn))
                        {
                            found = true;
                            break;
                        }
                    }

                    if (found)
                    {
                        foreach (var ff in _functions)
                            if (ff.Name.Equals(fn))
                                fun = ff;
                    }

                    if (!found)
                    {
                        throw new NoSuchFunctionException(StringResources.No_such_function_defined + ": " + fn);
                    }

                    var parser = new Parser();
                    foreach (var cfh in _customFunctions)
                        parser.AddCustomFunction(cfh.Key, cfh.Value);

                    foreach (var v in _variables)
                    {
                        if (v.Value.NumberType == NumberClass.NumberTypes.Float)
                        {
                            parser.AddVariable(v.Key, v.Value.FloatNumber);
                        }
                        if (v.Value.NumberType == NumberClass.NumberTypes.Integer)
                        {
                            parser.AddVariable(v.Key, v.Value.IntNumber);
                        }
                        if (v.Value.NumberType == NumberClass.NumberTypes.Expression)
                        {
                            parser.AddVariable(v.Key, v.Value.Expression);
                        }
                    }

                    foreach (var f in _functions)
                    {
                        parser.AddFunction(f.Name, f.Arguments, f.Expression);
                    }
                    var expressionList = new List<NumberClass>();

                    foreach (var expression in expressions)
                    {
                        SimplificationReturnValue simRetval = parser.Simplify(expression);

                        var numClass = new NumberClass();
                        if (simRetval.ReturnType == SimplificationReturnValue.ReturnTypes.Float)
                        {
                            numClass.FloatNumber = simRetval.DoubleValue;
                            numClass.NumberType = NumberClass.NumberTypes.Float;
                        }
                        if (simRetval.ReturnType == SimplificationReturnValue.ReturnTypes.Integer)
                        {
                            numClass.IntNumber = simRetval.IntValue;
                            numClass.NumberType = NumberClass.NumberTypes.Integer;
                        }
                        expressionList.Add(numClass);
                    }

                    if (fun != null)
                    {
                        var numClass = new NumberClass { NumberType = NumberClass.NumberTypes.Expression, Expression = fun.Expression };

                        SimplificationReturnValue sretval = parser.EvaluateFunction(numClass, fun, expressionList);

                        if (sretval != null && sretval.ReturnType == SimplificationReturnValue.ReturnTypes.Integer)
                        {
                            token.TokenName = TokenParser.Tokens.Integer;
                            token.TokenValue = sretval.IntValue.ToString();
                        }
                        if (sretval != null && sretval.ReturnType == SimplificationReturnValue.ReturnTypes.Float)
                        {
                            token.TokenName = TokenParser.Tokens.Float;
                            token.TokenValue = sretval.DoubleValue.ToString();
                        }
                    }
                }

                if (token.TokenName == TokenParser.Tokens.Variable)
                {
                    if (_variables.ContainsKey(token.TokenValue))
                    {
                        var z = _variables[token.TokenValue];

                        if (z.NumberType == NumberClass.NumberTypes.Float)
                        {
                            token.TokenName = TokenParser.Tokens.Float;
                            token.TokenValue = z.FloatNumber.ToString();
                        }
                        else if (z.NumberType == NumberClass.NumberTypes.Integer)
                        {
                            token.TokenName = TokenParser.Tokens.Integer;
                            token.TokenValue = z.IntNumber.ToString();
                        }
                    }
                    else
                    {
                        throw new NoSuchVariableException(StringResources.Undefined_Variable + ": " + token.TokenValue);
                    }
                }

                if (token.TokenName == TokenParser.Tokens.Whitespace || token.TokenName == TokenParser.Tokens.Newline)
                {
                    token = tp.GetToken();
                    continue;
                }
                if (token.TokenName == TokenParser.Tokens.Integer || token.TokenName == TokenParser.Tokens.Float)
                {
                    var nc = new NumberClass();

                    switch (token.TokenName)
                    {
                        case TokenParser.Tokens.Float:
                            nc.NumberType = NumberClass.NumberTypes.Float;
                            nc.FloatNumber = double.Parse(token.TokenValue);
                            break;
                        case TokenParser.Tokens.Integer:
                            nc.NumberType = NumberClass.NumberTypes.Integer;
                            nc.IntNumber = int.Parse(token.TokenValue);
                            break;
                    }
                    _outputQueue.Enqueue(nc);
                }
                if (IsOperator(token.TokenName))
                {
                    if (_operatorStack.Count > 0)
                    {
                        while (_operatorStack.Count > 0)
                        {
                            var op = _operatorStack.Peek(); //o2

                            if (op == "(" || op == ")")
                                break;
                            if ((GetPrecedence(token.TokenName) <= GetPrecedence(op) &&
                                 IsLeftAssociative(token.TokenValue)) ||
                                !IsLeftAssociative(token.TokenValue) &&
                                GetPrecedence(token.TokenName) < GetPrecedence(op))
                            {
                                op = _operatorStack.Pop();
                                var nc = new NumberClass { NumberType = NumberClass.NumberTypes.Operator, Operator = op };

                                _outputQueue.Enqueue(nc);
                            }
                            else break;
                        }
                    }
                    _operatorStack.Push(token.TokenValue);
                }
                if (token.TokenName == TokenParser.Tokens.Lparen)
                    _operatorStack.Push(token.TokenValue);
                if (token.TokenName == TokenParser.Tokens.Rparen)
                {
                    if (_operatorStack.Count > 0)
                    {
                        var op = _operatorStack.Pop();

                        while (op != "(")
                        {
                            var nc = new NumberClass { Operator = op, NumberType = NumberClass.NumberTypes.Operator };

                            _outputQueue.Enqueue(nc);

                            if (_operatorStack.Count > 0)
                                op = _operatorStack.Pop();
                            else
                            {
                                throw new MismatchedParenthesisException();
                            }
                        }
                    }
                    else
                    {
                        throw new MismatchedParenthesisException();
                    }
                }
                token = tp.GetToken();
            }

            while (_operatorStack.Count > 0)
            {
                var op = _operatorStack.Pop();

                if (op == "(" || op == ")")
                {
                    throw new MismatchedParenthesisException();
                }

                var nc = new NumberClass { NumberType = NumberClass.NumberTypes.Operator, Operator = op };

                _outputQueue.Enqueue(nc);
            }

            bool floatAnswer = false;
            bool slashAnswer = false;

            foreach(var v in _outputQueue)
            {
                if(v.NumberType == NumberClass.NumberTypes.Float)
                {
                    floatAnswer = true;
                }

                if(v.Operator == "/")
                {
                    slashAnswer = true;
                }
            }

            if (floatAnswer || slashAnswer)
            {
                var dblStack = new Stack<double>();

                foreach (var nc in _outputQueue)
                {
                    if (nc.NumberType == NumberClass.NumberTypes.Integer)
                        dblStack.Push(nc.IntNumber);

                    if (nc.NumberType == NumberClass.NumberTypes.Float)
                        dblStack.Push(nc.FloatNumber);

                    if (nc.NumberType == NumberClass.NumberTypes.Operator)
                    {
                        double val = DoMath(nc.Operator, dblStack.Pop(), dblStack.Pop());
                        dblStack.Push(val);
                    }
                }

                if (dblStack.Count == 0)
                    throw new CouldNotParseExpressionException();

                retval.DoubleValue = dblStack.Pop();
                retval.ReturnType = SimplificationReturnValue.ReturnTypes.Float;
            }
            else
            {
                var intStack = new Stack<int>();

                foreach (var nc in _outputQueue)
                {
                    if (nc.NumberType == NumberClass.NumberTypes.Integer)
                        intStack.Push(nc.IntNumber);

                    if (nc.NumberType == NumberClass.NumberTypes.Float)
                        intStack.Push((int)nc.FloatNumber);

                    if (nc.NumberType == NumberClass.NumberTypes.Operator)
                    {
                        int val = DoMath(nc.Operator, intStack.Pop(), intStack.Pop());
                        intStack.Push(val);
                    }
                }

                if (intStack.Count == 0)
                    throw new CouldNotParseExpressionException();

                retval.IntValue = intStack.Pop();
                retval.ReturnType = SimplificationReturnValue.ReturnTypes.Integer;
            }

            return retval;
        }
Ejemplo n.º 34
0
        public void AddVariable(string varName, string value)
        {
            var nc = new NumberClass { NumberType = NumberClass.NumberTypes.Expression, Expression = value };

            AddVariable(varName, nc);
        }
Ejemplo n.º 35
0
        public void AddVariable(string varName, double value)
        {
            var nc = new NumberClass { NumberType = NumberClass.NumberTypes.Float, FloatNumber = value };

            AddVariable(varName, nc);
        }
Ejemplo n.º 36
0
        public void AddVariable(string varName, int value)
        {
            var nc = new NumberClass { NumberType = NumberClass.NumberTypes.Integer, IntNumber = value };

            AddVariable(varName, nc);
        }
Ejemplo n.º 37
0
        private void AddVariable(string varName, NumberClass valueType)
        {
            if (_variables.ContainsKey(varName))
            {
                throw new VariableAlreadyDefinedException(StringResources.Variable_already_defined + ": " + varName);
            }

            if (valueType.NumberType == NumberClass.NumberTypes.Expression)
            {
                SimplificationReturnValue eeVal;

                eeVal = EvaluateExpression(valueType);

                if (eeVal.ReturnType == SimplificationReturnValue.ReturnTypes.Float)
                {
                    AddVariable(varName, eeVal.DoubleValue);
                    return;
                }
                if (eeVal.ReturnType == SimplificationReturnValue.ReturnTypes.Integer)
                {
                    AddVariable(varName, eeVal.IntValue);
                    return;
                }
            }
            _variables.Add(varName, valueType);
        }
Ejemplo n.º 38
0
        private SimplificationReturnValue EvaluateExpression(NumberClass expression)
        {
            var parser = new Parser();

            foreach (var cfh in _customFunctions)
                parser.AddCustomFunction(cfh.Key,cfh.Value);

            foreach (var v in _variables)
            {
                if (v.Value.NumberType == NumberClass.NumberTypes.Float)
                {
                    parser.AddVariable(v.Key, v.Value.FloatNumber);
                }
                if (v.Value.NumberType == NumberClass.NumberTypes.Integer)
                {
                    parser.AddVariable(v.Key, v.Value.IntNumber);
                }
                if (v.Value.NumberType == NumberClass.NumberTypes.Expression)
                {
                    parser.AddVariable(v.Key, v.Value.Expression);
                }
            }

            foreach (var f in _functions)
            {
                parser.AddFunction(f.Name, f.Arguments, f.Expression);
            }
            return parser.Simplify(expression.Expression);
        }
Ejemplo n.º 39
0
 private void EvaluateFunction(NumberClass expression, FunctionClass fc)
 {
     EvaluateFunction(expression, fc, new List<NumberClass> {
                        new NumberClass {NumberType = NumberClass.NumberTypes.Integer, IntNumber = 0}});
 }
Ejemplo n.º 40
0
		public void TestVirtualCall ()
		{
			var cls = new NumberClass (5);
			Assert.AreEqual (5, cls.Number, "#1");
			Assert.AreEqual (-5, cls.NegativeNumber, "#2");
		}
Ejemplo n.º 41
0
        private SimplificationReturnValue EvaluateFunction(NumberClass expression, FunctionClass fc, IEnumerable<NumberClass> ncList2)
        {
            var parser = new Parser();
            var ncList = new List<NumberClass>(ncList2);

            foreach (var cfr in _customFunctions)
                parser.AddCustomFunction(cfr.Key, cfr.Value);

            foreach (var v in _variables)
            {
                if (v.Value.NumberType == NumberClass.NumberTypes.Float)
                {
                    parser.AddVariable(v.Key, v.Value.FloatNumber);
                }
                if (v.Value.NumberType == NumberClass.NumberTypes.Integer)
                {
                    parser.AddVariable(v.Key, v.Value.IntNumber);
                }
                if (v.Value.NumberType == NumberClass.NumberTypes.Expression)
                {
                    parser.AddVariable(v.Key, v.Value.Expression);
                }
            }

            foreach (var f in _functions)
            {
                parser.AddFunction(f.Name, f.Arguments, f.Expression);
            }

            int ndx = 0;
            foreach (var a in fc.Arguments)
            {
                NumberClass nc = ndx >= ncList.Count ?
                    new NumberClass
                    {
                        NumberType = NumberClass.NumberTypes.Integer,
                        IntNumber = 0
                    } : ncList[ndx];

                if (nc.NumberType == NumberClass.NumberTypes.Float)
                {
                    try
                    {
                        parser.AddVariable(a, nc.FloatNumber);
                    } catch
                    {}
                }
                if (nc.NumberType == NumberClass.NumberTypes.Integer)
                {
                    try
                    {
                        parser.AddVariable(a, nc.IntNumber);
                    }catch
                    {
                    }
                }
                if (nc.NumberType == NumberClass.NumberTypes.Expression)
                    parser.AddVariable(a, nc.Expression);
                ndx++;
            }

            return parser.Simplify(expression.Expression);
        }