Go4Expert

Go4Expert (http://www.go4expert.com/)
-   C++ (http://www.go4expert.com/forums/cpp/)
-   -   Need some help for calc code (http://www.go4expert.com/forums/help-calc-code-t19703/)

gabuchia 8Oct2009 19:41

Need some help for calc code
 
:D, so I have this calc code, its accepts strings then calculates it. Can anyone explain what does the function. I can understand the bool check function though!

double value_of_num(const string &Expr) and double Value_Of_Expr(const string &Expr)

Code:

class Calculator : protected base
{
      enum {PLUS='+',MINUS='-',MUL='*',DIV='/'}; // Enumeration declaration : User defined type of a set of constants called enumerators
      int precision;
      double Value_Of_Num(const string &Expr)

      {
          istringstream is(Expr);
          double value=0.0;
          is >> value;
          cout << setprecision(precision) << value;
      }

      double Value_Of_Expr(const string &Expr)

      {
          int i=0,p=0,pos_mul=0,pos_div=0;

          if(Expr.at(0)=='('&&Expr.at(Expr.length()-1)==')')
          {
                for(i=0;i < Expr.length();i++)
                {
                 
                    if(Expr.at(i)=='(') p++;
                    else if(Expr.at(i)==')') p--;
                    if(p==0) break;
       
                }

                if(i==Expr.length()-1)
                return Value_Of_Expr(Expr.substr(1,Expr.length()-2));
          }

            for(i=0;i < Expr.length();i++)
            {
                  if(Expr.at(i)=='(') p++;
                  else if(Expr.at(i)==')') p--;
                  else if(p==0&&ispunct(Expr.at(i)))
                      {
       
                      switch(Expr.at(i))
                                  {
                                            case PLUS:
                                            return Value_Of_Expr(Expr.substr(0,i))+Value_Of_Expr(Expr.substr(i+1,Expr.length()-i-1));
                                            case MINUS:
                                            return Value_Of_Expr(Expr.substr(0,i))-Value_Of_Expr(Expr.substr(i+1,Expr.length()-i-1));
                                            case MUL: pos_mul=i;
                            break;
                                            case DIV: pos_div=i;
                            break;
     
                      }
                  }
            }

      if(pos_mul)
      return Value_Of_Expr(Expr.substr(0,pos_mul))*Value_Of_Expr(Expr.substr(pos_mul+1,Expr.length()-pos_mul-1));
 
      if(pos_div)
      return Value_Of_Expr(Expr.substr(0,pos_div))/Value_Of_Expr(Expr.substr(pos_div+1,Expr.length()-pos_div-1));
 
      return Value_Of_Num(Expr);
      }


      // several important validation checks on the input
      bool Check(string input_string)
      {
          // Checks for repeated usage of '+', '-', '*', '/' operators
          for (int r = 0; r < input_string.length(); r++)
          {
                if((input_string[r]=='+')||(input_string[r]=='-')||(input_string[r]=='*')||(input_string[r]=='/'))
                {
                    if((input_string[r+1]=='+')||(input_string[r+1]=='-')||(input_string[r+1]=='*')||(input_string[r+1]=='/'))
                    {
                          return false;
                    }
                }
          }
          // Checks for the last character of the string equation
          int g = input_string.length() ;
          if(input_string[g-1] == '*' || input_string[g-1] =='/' || input_string[g-1] == '-' || input_string[g-1] == '+')
          {
                return false;
          }
          string array="0123456789+-*/()";
          int count=0;
          for (int s=0; s < input_string.length(); s++)
          {
                for(int z=0; z < array.length(); z++)
                {
                    //Compares each number/operator with elements from 'array'
                    if(input_string[s]==array[z])
                    {
                          count++;
                    }
                }
          }
          //every number/operator approved should be equals to input
          if (count == input_string.length())
          {
                return true;
          }
          else
          {
                return false;
          }
      }
      public :
      Calculator()
      {
          string expression;
         
          system("CLS");
              cout << "                  Welcome to the calculator function!" << endl;
              cout << "" << endl;
              cout << "" << endl;
              cout << "With this calculator, your problem solving is made simple." << endl;
              cout << "You do not have to calculate each part of an expression one at a time \n";
          cout << "like you do with you simple calculators." << endl;
              cout << "All you have to do is simply input an expression \n";
          cout << "and the calculator will give you the answer." << endl;

         
                    cout << "" << endl;
                cout << "Enter your expression:";
                cin >> expression;
                cout << "How many decimal places would you want your answer to be in?" << endl;
                cin >> precision;
                if(Check(expression)==true)
                {
                    cout << Value_Of_Expr(expression)<<endl;
                }
                else
                {
                    cout << "" <<endl;
                    cout << "Error in the input" << endl;
                }
                cout << endl << endl << endl;
                Calculator_1:
                base calculator1;
                calculator1.display();
               
               
                       
      }
};


xpi0t0s 9Oct2009 16:23

Re: Need some help for calc code
 
It's unlikely anyone will give you a line by line breakdown of the entire function. What precisely do you want to know? Have you tried asking the person who wrote the code?

gabuchia 10Oct2009 14:54

Re: Need some help for calc code
 
Sadly, the author of this code did not leave his contact email. =(

double Value_Of_Num(const string &Expr)

this function is the one that's making my head spin, its only 4 lines long, thanks in advance for explaining!

xpi0t0s 10Oct2009 21:40

Re: Need some help for calc code
 
As the name suggests it gets the value of a number. So for "27" it would return 27.

gabuchia 11Oct2009 07:03

Re: Need some help for calc code
 
My question will be, why does it need to create an object 'is' with istringstream.

And what does this line mean

Code:

is >> value;

xpi0t0s 11Oct2009 15:05

Re: Need some help for calc code
 
Presumably because istringstream implements a conversion to double, whereas string doesn't. So you convert the string Expr to an istringstream with "istringstream is(Expr)", then invoke istringstream::operator>>(double), which performs the conversion, with "is >> value".

A lot of C++ is about knowing your standard library.

gabuchia 11Oct2009 22:45

Re: Need some help for calc code
 
So you're saying its essentially converting the value of Expr into an istringstream. Then it converts the 'is' which is created by the string 'Expr' and in the line of the code

Code:

is >> value
it converts 'is' into a double because value is declared as a double type data. Am I getting this right?

gabuchia 14Oct2009 15:12

Re: Need some help for calc code
 
As pointed by my friend, we noticed that the calculator does not take in negative numbers, is there any code that I should change to let it accept negative numbers?

ie :
(5*5)-(2*2)*-5

xpi0t0s 14Oct2009 18:21

Re: Need some help for calc code
 
The code currently treats consecutive operators an error, so 3+-5 would throw an error because of the +-. It would need to be modified to throw an error only when this doesn't make sense, so for example 3+-5 is fine because it means three plus (-5), but 3+*5 would still throw an error.

Have a look at the code after the comment "// several important validation checks on the input"

gabuchia 29Oct2009 20:45

Re: Need some help for calc code
 
Quote:

Originally Posted by xpi0t0s (Post 58839)
The code currently treats consecutive operators an error, so 3+-5 would throw an error because of the +-. It would need to be modified to throw an error only when this doesn't make sense, so for example 3+-5 is fine because it means three plus (-5), but 3+*5 would still throw an error.

Have a look at the code after the comment "// several important validation checks on the input"

I have changed several codes of it, but it still wouldn't take a negative number. Here is the code, can you give me some suggestions?

Code:

class Calculator : protected base
{
      enum {PLUS='+',MINUS='-',MUL='*',DIV='/'};
      int precision;
      double Value_Of_Num(const string &Expr)

      {
          istringstream is(Expr);
          double value;
          is >> value;
          return value;
      }
      double Value_Of_Expr(const string &Expr)

      {
          int i=0,p=0,pos_mul=0,pos_div=0;

          if(Expr.at(0)=='('&&Expr.at(Expr.length()-1)==')')
          {
                for(i=0;i < Expr.length();i++)
                    {
                 
                    if(Expr.at(i)=='(') p++;
                    else if(Expr.at(i)==')') p--;
                    if(p==0) break;
       
                }

                if(i==Expr.length()-1)
                return Value_Of_Expr(Expr.substr(1,Expr.length()-2));
          }

          for(i=0;i < Expr.length();i++)
          {
                if(Expr.at(i)=='(') p++;
                else if(Expr.at(i)==')') p--;
                        else if(p==0&&ispunct(Expr.at(i)))
                        {
       
                            switch(Expr.at(i))
                                {
                                          case PLUS:
                                          return Value_Of_Expr(Expr.substr(0,i))+Value_Of_Expr(Expr.substr(i+1,Expr.length()-i-1));
                                          case MINUS:
                                          return Value_Of_Expr(Expr.substr(0,i))-Value_Of_Expr(Expr.substr(i+1,Expr.length()-i-1));
                                          case MUL: pos_mul=i; break;
                                          case DIV: pos_div=i; break;
     
                    }
                }
          }

          if(pos_mul)
          return Value_Of_Expr(Expr.substr(0,pos_mul))*Value_Of_Expr(Expr.substr(pos_mul+1,Expr.length()-pos_mul-1));
 
          if(pos_div)
          return Value_Of_Expr(Expr.substr(0,pos_div))/Value_Of_Expr(Expr.substr(pos_div+1,Expr.length()-pos_div-1));
 
          return Value_Of_Num(Expr);
      }


      // several important validation checks on the input
      bool Check(string input_string)
      {

          for (int r = 0; r <= input_string.length(); r++)
          {
                if((input_string[r]=='+')||(input_string[r]=='-'))
                {
                    if((input_string[r+1]=='+')||(input_string[r+1]=='-')||(input_string[r+1]=='*')||(input_string[r+1]=='/'))
                    {
                        return false;
                    }
                }
          }
          for (int r = 0; r <= input_string.length(); r++)
          {
                if((input_string[r]=='*')||(input_string[r]=='/'))
                {
                    if((input_string[r+1]=='*')||(input_string[r+1]=='/'))
                    {
                        return false;
                    }
                }
          }
          string array="0123456789+-*/().";
          int count=0;
          for (int s=0; s < input_string.length(); s++)
          {
                for(int z=0; z < array.length(); z++)
                {
                    if(input_string[s]==array[z])
                    {
                          count++;
                    }
                }
          }
          if (count == input_string.length())
          {
                if(input_string.at(0) != '*' && input_string.at(0) != '/' && input_string.at(0) != '+' && input_string.at(0) != '-')
                {
                    if(input_string.at(input_string.length()-1) != '*' && input_string.at(input_string.length()-1) != '/' && input_string.at(input_string.length()-1) != '+' && input_string.at(input_string.length()-1) != '-')
                    {
                          return true;
                    }
                }
          }
          else
          {
                return false;
          }
      }
      public :
      Calculator()
      {
          string expression, choice;
         
          system("CLS");
          system("COLOR 03");
              cout << "\t\t\tWelcome to the calculator function!" << endl;
              cout << "" << endl;
              cout << "" << endl;
              cout << "With this calculator, your problem solving is made simple." << endl;
              cout << "You do not have to calculate each part of an expression one at a time \n";
          cout << "like you do with you simple calculators." << endl;
              cout << "All you have to do is simply input an expression \n";
          cout << "and the calculator will give you the answer." << endl;
          cout << "" << endl;
          cout << "Enter your expression:";
          cin >> expression;
          if(Check(expression)==true)
          {
                cout << "Does your expression require precision of significant figures?[y/n]: ";
                cin >> choice;
                cout << endl;
                if(choice == "y" || choice == "Y")
                {
                    cout << "How many significant figures do you want it to display?" << endl;
                    cin >> precision;
                    cout << setprecision(precision) << Value_Of_Expr(expression)<<endl;                       
                }
                else
                {
                    cout << "The answer is: ";
                    cout << Value_Of_Expr(expression)<<endl;
                }
          }
          else
          {
                cout << "\a" <<endl;
                cout << "Error in the input" << endl;
          }
          cout << endl << endl << endl;
          base calculator1;
          calculator1.display();
               
               
                       
      }
};



All times are GMT +5.5. The time now is 11:50.