Need some help for calc code

Discussion in 'C++' started by gabuchia, Oct 8, 2009.

  1. gabuchia

    gabuchia New Member

    Joined:
    Oct 4, 2009
    Messages:
    11
    Likes Received:
    0
    Trophy Points:
    0
    :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();
                    
                    
                            
          }
    };
     
  2. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    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?
     
  3. gabuchia

    gabuchia New Member

    Joined:
    Oct 4, 2009
    Messages:
    11
    Likes Received:
    0
    Trophy Points:
    0
    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!
     
  4. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    As the name suggests it gets the value of a number. So for "27" it would return 27.
     
  5. gabuchia

    gabuchia New Member

    Joined:
    Oct 4, 2009
    Messages:
    11
    Likes Received:
    0
    Trophy Points:
    0
    My question will be, why does it need to create an object 'is' with istringstream.

    And what does this line mean

    Code:
    is >> value;
     
  6. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    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::eek:perator>>(double), which performs the conversion, with "is >> value".

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

    gabuchia New Member

    Joined:
    Oct 4, 2009
    Messages:
    11
    Likes Received:
    0
    Trophy Points:
    0
    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?
     
  8. gabuchia

    gabuchia New Member

    Joined:
    Oct 4, 2009
    Messages:
    11
    Likes Received:
    0
    Trophy Points:
    0
    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
     
  9. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    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"
     
  10. gabuchia

    gabuchia New Member

    Joined:
    Oct 4, 2009
    Messages:
    11
    Likes Received:
    0
    Trophy Points:
    0
    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();
                    
                    
                            
          }
    };
     
  11. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    Well the code still does this so I'm not surprised it doesn't accept negative numbers:
    Code:
                    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;
    
    because this specifically excludes something like "3+-5".

    Expression evaluation code is not in general simple to write, and more difficult to read and modify particularly when the code has as few comments as yours does. So I can't really make any suggestions except that you think carefully through what it is supposed to do, with pen and paper away from the computer. Decide on an initial algorithm, write several expressions out and work through that algorithm as the computer would: character by character, keeping track of variable contents, and following the algorithm strictly, being careful to do *exactly* what the algorithm states and NOT what you think it means. This isn't easy, and perhaps it would be helpful to talk through it with someone who can point out when you're doing what you meant rather than what you have written down.

    You can then use that process to modify the algorithm so that it works with the example expressions you've thought up.

    This is called a "dry run" and is a VERY important skill that all programmers *need*.
     
  12. gabuchia

    gabuchia New Member

    Joined:
    Oct 4, 2009
    Messages:
    11
    Likes Received:
    0
    Trophy Points:
    0
    If I were to remove the checking of 5--5, it would give me an error, if I enter that expression. Runtime error to be precise, any other suggestions?
     
  13. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    Solving this is not going to be as simplistic as just removing a bit of code. This is a complex project and you NEED to study what I suggested in my last post. If you don't want to do that then this project is beyond your abilities and you should look for something simpler.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice