예제 #1
0
        public static bool DoMaths(ref string number, ref double l1, ref double l2, ref Operation op, Operation newOp, ref bool firstOperation)
        {
            // Do not assign l2 if it's first time
            if (!firstOperation)
            {
                if (!double.TryParse(number, out l2))
                {
                    number = MUtil.ExpNotationToDecimalNotation(number);
                    if (!double.TryParse(number, out l1))
                    {
                        Debug.LogError("Cannot parse " + number + " to number ( double )");
                        return(false);
                    }
                }



                l1 = op.function.Invoke(l1, l2);
            }
            else
            {
                firstOperation = false;
            }
            number = "";
            op     = newOp;

            return(true);
        }
예제 #2
0
        public static double Calculate(string data)
        {
            if (data.Length == 0)
            {
                Debug.LogError("Data is empty");
                return(double.NaN);
            }

            if (operations == null)
            {
                FillOperationsList();
            }

            if (bracketsFunctions == null)
            {
                FillBracketsFunctions();
            }

            data = MUtil.RemoveSpaces(data);

            data = ChangePunctuationMark(data);
            data = MUtil.ExpNotationToDecimalNotation(data);

            data = ReplaceConstants(data);

            data = CalculateBrackets(data);
            if (data.StartsWith("E"))
            {
                return(double.NaN);
            }


            data = CalculateExpression(data);


            double result = 0;

            if (!double.TryParse(data, out result))
            {
                Debug.LogError("Cannot parse " + data + " to result ( double )");
                return(double.NaN);
            }

            return(result);
        }
예제 #3
0
        /// <summary>
        /// Gets bracket operation and creates list from them
        /// </summary>
        /// <param name="data">String with expression</param>
        /// <param name="bracketOperations"></param>
        /// <returns>Data without brackets operations</returns>
        private static string CalculateBrackets(string data)
        {
            string actExpr      = "";
            string specialMode  = "";
            int    bracketLevel = 0;

            List <BracketOperation> bracketOperations = new List <BracketOperation>();

            for (int i = 0; i < data.Length; i++)
            {
                if (bracketLevel > 0)
                {
                    actExpr += data[i];
                }

                if (data[i] == ')')
                {
                    if (bracketLevel > 1)
                    {
                        bracketLevel--;
                    }
                    else if (bracketLevel == 1)
                    {
                        BracketOperation operation = new BracketOperation(actExpr.Remove(0, 1).Remove(actExpr.Length - 2, 1), i - actExpr.Length + 1 - specialMode.Length);
                        if (specialMode.Length > 0)
                        {
                            Function f = FindFunction(specialMode, true);
                            if (f == null)
                            {
                                Debug.LogError("Cannot find function " + specialMode);
                                return("ENOFUNCTION");
                            }

                            operation.specialFunction = f;
                        }


                        //Debug.Log("Bracket operation: \"" + operation.operation + "\"");
                        //Debug.Log("Bracket operation start: " + operation.positionInString);

                        bracketOperations.Add(operation);


                        data        = data.Remove(i - actExpr.Length + 1 - specialMode.Length, actExpr.Length + specialMode.Length);
                        i          -= actExpr.Length + specialMode.Length;
                        actExpr     = "";
                        specialMode = "";

                        bracketLevel = 0;
                    }
                    else
                    {
                        Debug.LogError("Closing bracket without opening");
                        return(double.NaN.ToString());
                    }
                }
                else if (data[i] == '(')
                {
                    bracketLevel++;
                    if (bracketLevel == 1)
                    {
                        actExpr += data[i];
                        string s = "";
                        for (int j = i - 1; j >= 0; j--)
                        {
                            if (MUtil.IsNumber(data[j]))
                            {
                                break;
                            }
                            if (FindOperation(data[j]) != null)
                            {
                                break;
                            }

                            s           = "" + data[j];
                            specialMode = specialMode.Insert(0, s);
                        }
                    }
                }
            }

            //Debug.Log("Bracket level: " + bracketLevel);
            if (bracketLevel > 0)
            {
                Debug.LogError("No closing bracket");
                return("ENOCLOSEBRACKET");
            }

            // Recurently get additional brackets from brackets
            for (int i = 0; i < bracketOperations.Count; i++)
            {
                BracketOperation op = bracketOperations[i];
                op.operation         = CalculateBrackets(bracketOperations[i].operation);
                bracketOperations[i] = op;
            }

            // Calcualate brackets
            for (int i = 0; i < bracketOperations.Count; i++)
            {
                string rtBeforeComma  = "";
                string rtAfterComma   = "";
                bool   rtIsAfterComma = false;

                string result;

                // Two args functions
                if (bracketOperations[i].specialFunction != null && bracketOperations[i].specialFunction.function == null && bracketOperations[i].specialFunction.twoArgFunction != null)
                {
                    for (int j = 0; j < bracketOperations[i].operation.Length; j++)
                    {
                        if (bracketOperations[i].operation[j] == ';')
                        {
                            rtIsAfterComma = true;
                            continue;
                        }

                        if (rtIsAfterComma)
                        {
                            rtAfterComma += bracketOperations[i].operation[j];
                        }
                        else
                        {
                            rtBeforeComma += bracketOperations[i].operation[j];
                        }
                    }

                    rtBeforeComma = CalculateExpression(rtBeforeComma);
                    //Debug.Log("rtBeforeComma after: " + rtBeforeComma);
                    rtAfterComma = CalculateExpression(rtAfterComma);
                    //Debug.Log("rtAfterComma after: " + rtAfterComma);

                    result = "0";
                }
                else
                {
                    result = CalculateExpression(bracketOperations[i].operation);
                }
                double res;
                if (!double.TryParse(result, out res))
                {
                    Debug.LogError("Cannot convert " + result + " to result ( double )");
                    return("ECONVERSION");
                }

                if (bracketOperations[i].specialFunction != null)
                {
                    if (bracketOperations[i].specialFunction.function != null)
                    {
                        res    = bracketOperations[i].specialFunction.function.Invoke(res);
                        result = MUtil.ToStandardNotationString(res);
                        if (result.Length == 0)
                        {
                            result = "0";
                        }
                    }
                    else
                    {
                        if (bracketOperations[i].specialFunction.function == null && bracketOperations[i].specialFunction.twoArgFunction != null)
                        {
                            if (rtBeforeComma.Length == 0 || rtAfterComma.Length == 0)
                            {
                                Debug.LogError("Bad 2 arg function arguments");
                                return("EBADROOTARG");
                            }
                            else
                            {
                                double l1;
                                double n;
                                if (!double.TryParse(rtBeforeComma, out l1))
                                {
                                    Debug.LogError("Cannot convert first root argument to l1 ( double )");
                                    return("EBADCONVERSION");
                                }
                                if (!double.TryParse(rtAfterComma, out n))
                                {
                                    Debug.LogError("Cannot convert second root argument to n ( double )");
                                    return("EBADCONVERSION");
                                }

                                res    = bracketOperations[i].specialFunction.twoArgFunction(l1, n); //OperationFunctions.Rt(l1, n);
                                result = MUtil.ToStandardNotationString(res);
                                if (result.Length == 0)
                                {
                                    result = "0";
                                }
                            }
                        }
                    }

                    //Debug.Log("Result: " + result);
                }

                data = data.Insert(bracketOperations[i].positionInString, result);

                // Fix offsets
                for (int j = i + 1; j < bracketOperations.Count; j++)
                {
                    BracketOperation tOp = bracketOperations[j];
                    tOp.positionInString += result.Length;

                    bracketOperations[j] = tOp;
                }
            }

            return(data);
        }
예제 #4
0
 public static double Power(double l1, double l2)
 {
     return(MUtil.Power(l1, l2));
 }
예제 #5
0
        public static string CalculateSpecificOperations(string data, Operation[] allowedOperations)
        {
            double    l1 = 0, l2 = 0;
            Operation op = null; // First operation is always addition


            string actualNumber    = "";
            bool   noPrevOperators = true;

            bool operationIsAllowed = false;

            int    startIndex = 0;
            string startData  = "";

            for (int i = 0; i < data.Length; i++)
            {
                op = FindOperation(data[i]);

                if (op != null)
                {
                    if (i == 0 && data[0] == '-')
                    {
                        startData += data[0];
                        continue;
                    }
                    startIndex = i;
                    break;
                }

                startData += data[i];
            }

            // No operator
            if (op == null)
            {
                return(data);
            }

            if (startIndex == 0)
            {
                Debug.LogError("Operator without number: \"" + data + "\" op: " + op.name);
                return("EOPWTHTNMBR");
            }



            if (!double.TryParse(startData, out l1))
            {
                if (startData[startData.Length - 1] == 'E')
                {
                    for (int i = startData.Length; i < data.Length; i++)
                    {
                        if (MUtil.IsNumber(data[i]) || data[i] == '+')
                        {
                            startData += data[i];
                        }
                        else
                        {
                            break;
                        }
                    }

                    for (int i = 0; i < data.Length; i++)
                    {
                        if (data[i] == 'E')
                        {
                            if (data.Length > i + 1)
                            {
                                if (data[i + 1] == '+')
                                {
                                    i += 2;
                                }
                            }
                        }

                        op = FindOperation(data[i]);
                        if (op != null)
                        {
                            break;
                        }
                    }

                    l1   = MUtil.GetDoubleFromExpNotation(startData);
                    data = data.Remove(0, startData.Length);

                    string decimalStartData = MUtil.ExpNotationToDecimalNotation(startData);
                    data      = data.Insert(0, decimalStartData);
                    startData = decimalStartData;

                    startIndex = startData.Length;

                    Debug.Log("Data after converting exponent notation: " + data);
                }
                else
                {
                    Debug.LogError("Cannot convert " + startData + " to l1 ( double )");
                    return("ECONVERSION");
                }

                if (l1.Equals(double.NaN))
                {
                    Debug.LogError("Cannot convert " + startData + " to l1 ( double ). l1 = NaN");
                    return("ECONVERSION");
                }
            }

            actualNumber = startData;
            bool firstOperation = true;

            // Multiply
            for (int i = startIndex; i < data.Length; i++)
            {
                Operation aop = FindOperation(data[i]);
                if (aop != null)
                {
                    if (actualNumber.Length == 0 && data[i] == '-')
                    {
                        actualNumber += data[i];
                        continue;
                    }

                    operationIsAllowed = false;
                    for (int j = 0; j < allowedOperations.Length; j++)
                    {
                        if (op == allowedOperations[j])
                        {
                            operationIsAllowed = true;
                            break;
                        }
                    }
                    if (operationIsAllowed)
                    {
                        if (data[i] == '+' && i > 0 && (data[i - 1] == 'E'))
                        {
                            actualNumber += data[i];
                            continue;
                        }

                        //Debug.Log("Data before: " + data);
                        if (noPrevOperators)
                        {
                            data = data.Remove(0, actualNumber.Length);
                            i    = 0;
                        }
                        else
                        {
                            string l1Str = MUtil.ToStandardNotationString(l1);

                            data = data.Remove(i - actualNumber.Length - 1 - l1Str.Length, actualNumber.Length + 1 + l1Str.Length);
                            i   -= actualNumber.Length + 1 + l1Str.Length;
                        }

                        noPrevOperators = false;

                        //l1 = l2;

                        //actualNumber = MUtil.ExpNotationToDecimalNotation(actualNumber);

                        if (!DoMaths(ref actualNumber, ref l1, ref l2, ref op, aop, ref firstOperation))
                        {
                            return("ECONVERSION");
                        }


                        string standardNotL1 = MUtil.ToStandardNotationString(l1);

                        data         = data.Insert(i, standardNotL1);
                        i           += standardNotL1.Length;
                        actualNumber = "";
                        op           = aop;
                        //Debug.Log("Data after: " + data);
                    }
                    else
                    {
                        if (data[i] == '+' && i > 0 && (data[i - 1] == 'E'))
                        {
                            actualNumber += data[i];
                            continue;
                        }
                        if (!double.TryParse(actualNumber, out l1))
                        {
                            actualNumber = MUtil.ExpNotationToDecimalNotation(actualNumber);
                            if (!double.TryParse(actualNumber, out l1))
                            {
                                Debug.LogError("Cannot parse " + actualNumber + " to number ( double ) #2");
                                return("ECONVERSION");
                            }
                        }

                        op              = aop;
                        actualNumber    = "";
                        noPrevOperators = false;

                        firstOperation = false;
                    }
                }
                else
                {
                    actualNumber += data[i];
                }
            }

            operationIsAllowed = false;
            for (int j = 0; j < allowedOperations.Length; j++)
            {
                if (op == allowedOperations[j])
                {
                    operationIsAllowed = true;
                    break;
                }
            }
            if (operationIsAllowed)
            {
                if (data[data.Length - 1] == '+' && data.Length > 0 && (data[data.Length - 1] == 'E'))
                {
                    return(data);
                }

                //Debug.Log("l1.ToString(): " + MUtil.ExpNotationToDecimalNotation(l1.ToString()) + ", lenght: " + MUtil.ExpNotationToDecimalNotation(l1.ToString()).Length);
                string l1Str = MUtil.ToStandardNotationString(l1);
                data = data.Remove(data.Length - actualNumber.Length - 1 - l1Str.Length, actualNumber.Length + 1 + l1Str.Length);

                noPrevOperators = false;

                //l1 = l2;
                //actualNumber = MUtil.ExpNotationToDecimalNotation(actualNumber);

                if (!DoMaths(ref actualNumber, ref l1, ref l2, ref op, operations[0], ref firstOperation))
                {
                    return("ECONVERSION");
                }



                data = data.Insert(data.Length, MUtil.ToStandardNotationString(l1));
                //i += l1.ToString().Length;
                actualNumber = "";
                op           = operations[0];
                //Debug.Log("Data after: " + data);
            }


            return(data);
        }
예제 #6
0
        /// <summary>
        /// Calculates data and returns with result multiplied by 100
        /// </summary>
        /// <param name="args">Empty => user would be prompted to write data, args[0] => automatically calculate these</param>
        static void Main(string[] args)
        {
            const bool testMode = false;

            string dataToCalculate = "";

            if (args.Length > 0)
            {
                dataToCalculate = args[0];
            }
            else if (dataToCalculate.Length == 0 && !testMode)
            {
                while (dataToCalculate.Length == 0)
                {
                    Debug.Log("Write data to calculate: ", ConsoleColor.White, false);
                    dataToCalculate = Console.ReadLine();
                    Console.WriteLine(" ");
                }
            }

            if (dataToCalculate.Length == 0 && !testMode)
            {
                Debug.FatalError("Data to calculate is empty", -1, 5000);
                return;
            }

            if (dataToCalculate.ToLower() == "f")
            {
                Debug.Log("To pay respect", ConsoleColor.Yellow);
                return;
            }
            if (!testMode)
            {
                double result = MathFromString.Calculate(dataToCalculate);
                if (double.IsInfinity(result))
                {
                    Debug.LogWarning("Infinity");
                }
                else
                {
                    Debug.Log("Result: " + MUtil.ToStandardNotationString(result), ConsoleColor.Blue);
                }
            }
            else
            {
                double    result    = 0;
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();


                //dataToCalculate = "sqrt(1-(1256^2/1426789^2))/sin(6732+124)";
                const double x = 125123.1532;
                dataToCalculate = "(sqrt(2*" + x.ToString() + "+1)-sqrt(" + x.ToString() + "+6))/(2*" + x.ToString() + "^2-7*" + x.ToString() + "-15)";
                int retries = 1;

                double avg     = 0;
                int    repeats = 0;
                while (true)
                {
                    //Debug.Log("Test scientific notation: " + MUtil.ToStandardNotationString(2.5));

                    double mmath  = 0;
                    double native = 0;

                    stopwatch.Restart();



                    for (int i = 0; i < retries; i++)
                    {
                        result = MathFromString.Calculate(dataToCalculate);
                    }

                    stopwatch.Stop();
                    mmath = stopwatch.ElapsedTicks - 5;

                    //Debug.Log("Result: " + result, ConsoleColor.Yellow);
                    Console.Clear();

                    Debug.Log("MMathFromString result: " + result, ConsoleColor.Cyan);
                    Debug.Log("Time for " + retries + " retries: " + stopwatch.ElapsedMilliseconds + "ms, " + (stopwatch.ElapsedTicks - 5) + " ticks", ConsoleColor.Cyan);
                    Debug.Log("Time per calculation: " + (stopwatch.ElapsedMilliseconds) / (float)retries + "ms, " + (stopwatch.ElapsedTicks - 5) / (float)retries + " ticks\n", ConsoleColor.Cyan);


                    stopwatch.Restart();
                    for (int i = 0; i < retries; i++)
                    {
                        //result = MUtil.Power(1500,150) * MUtil.Power(1500, 150) / MUtil.Power(1500, 150);
                        //result = Math.Sin(Math.Pow(4, 1.5));
                        //result = Math.Sqrt(1 - (Math.Pow(1256, 2) / Math.Pow(1426789, 2))) / Math.Sin(6732 + 124);
                        result = (Math.Sqrt(2 * x + 1) - Math.Sqrt(x + 6)) / (2 * Math.Pow(x, 2) - 7 * x - 15);
                    }

                    stopwatch.Stop();
                    native = stopwatch.ElapsedTicks - 5;

                    Debug.Log("Native result: " + result, ConsoleColor.Yellow);
                    Debug.Log("Time for " + retries + " retries: " + stopwatch.ElapsedMilliseconds + "ms, " + (stopwatch.ElapsedTicks - 5) + " ticks", ConsoleColor.Yellow);
                    Debug.Log("Time per calculation: " + (stopwatch.ElapsedMilliseconds) / (float)retries + "ms, " + (stopwatch.ElapsedTicks - 5) / (float)retries + " ticks\n", ConsoleColor.Yellow);


                    repeats++;
                    avg += (mmath / native);
                    Debug.Log("\nAbout " + (int)(mmath / native) + "x slower", ConsoleColor.DarkMagenta);
                    Debug.Log("On averge: " + (int)(avg / repeats) + "x slower", ConsoleColor.Magenta);
                    Thread.Sleep(500);
                }

                Environment.Exit((int)(result * 100));
            }
        }