• Lucid Dreaming - Dream Views




    Results 1 to 16 of 16

    Threaded View

    1. #1
      Banned
      Join Date
      Apr 2007
      Location
      Out Chasing Rabbits
      Posts
      15,193
      Likes
      935

      Want to QA some C++ code?

      I wrote a library for a function that I needed in my company's scripting language. It's complex and 700 lines of code, so I'd like to have someone other than myself check it for bugs. Just give the math() function various expressions and see if the results come out right. The main function is the last one at the bottom. A list of functions is available here: Math Functions

      That page says that it supports hex values, but the number converter for this one doesn't, so don't use them

      Code:
      #include <iostream>
      #include <cmath>
      #include <sstream>
      
      using namespace std;
      
      #define e  2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274f
      #define pi 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679f
      
      #define e_string  "(2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274)"
      #define pi_string "(3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679)"
      
      
      string math(const string & exp);
      
      string ToString(long double v){
          stringstream out;
          out << v;
          string res(out.str());
          if (res == "inf") return "Infinity";
          if (res == "-inf") return "-Infinity";
          return res;
      }
      
      long double ToNumber(const string & s){
          return atof(s.c_str());
      }
      
      long double Factorial(int n){
          long double result = (long double)n;
          if (n < 2){  //0! = 1
      	   return 1.0f;
          } else {
      	   for (unsigned int value = n - 1; value > 1; --value){
      		  result *= (long double)value;
      	   } 
          }  
          return result;
      }
      
      long double logn(long double value, long double base){
          return (log10(value) / log10(base));
      }
      
      long double hyper(long double a, long double x){
          if (x <= -1.0f){
      	   return (logn(hyper(x + 1.0f, a), a));
          } else if (x > 0.0f){
      	   return (pow(a, hyper(x - 1.0f, a)));
          } else {
      	   long double part1 = ((2.0f * log10(a)) / (1.0f + log10(a))) * x;
      	   long double part2 = ((1.0f - log10(a)) / (1.0f + log10(a))) * (x * x);
      	   return 1.0f + part1 - part2;
          }
      }
      
      long double slog(long double z, long double b){
          if (z <= 0.0f){
      	   return slog(pow(b, z), b) - 1.0f;
          } else if (1.0 < z){
      	   return slog(logn(z, b), b) + 1.0f;
          } else {
      	   long double part1 = ((2.0f * log10(b)) / (1.0f + log10(b))) * z;
      	   long double part2 = ((1.0f - log10(b)) / (1.0f + log10(b))) * (z * z);
      	   return -1.0f + part1 + part2;
          }
      }
      
      string DoubleNegatives(string & exp){
          size_t pos = exp.find('-');
          string res;
          string funcs(")*+%/\\^-");
          while (pos != string::npos){
      	   if (pos){
      		  res += exp.substr(0, pos);
      	   }
      	   char c = '*';
      	   if (res.length()){
      		  c = res[res.length() - 1];
      	   } 
      	   if (funcs.find_first_of(c) != string::npos){  //negation
      		  if (exp[pos + 1] == '-'){  //double negative
      			 exp = exp.substr(pos + 2);
      		  } else {
      			 res += "-";
      			 exp = exp.substr(pos + 1); 
      		  }
      	   }	else {  //subtraction
      		  res += "-";
      		  exp = exp.substr(pos + 1);
      	   }
      	   pos = exp.find('-');
          }
          return res + exp;
      }
      
      size_t math_paren(const string & exp, size_t pos){
          size_t pos2 = pos + 1;
          int params = 0;
          while(exp[pos2]){
      	   switch(exp[pos2]){
      		  case '(':
      			 params++;
      			 break;
      		  case ')':
      			 if (!params) return pos2;
      			 params--;
      			 break;
      	   }
      	   pos2++;
          }
          return string::npos;
      }
      
      void CheckForFunction(string & side, bool front){
          size_t pos;
          pos = (front) ? side.find_last_not_of(' ') : side.find_first_not_of(' ');
          if (pos == string::npos) return;
          char c = side[pos];
          string funcs("<>%^*/+-hnsctglrdmaw");
          if (funcs.find_first_of(c) != string::npos) return;
          if (front){
      	   side += "*";
          } else {
      	   side = string("*") + side;
          }	   
      }
      
      void Split(const string & exp, long double & p1, long double & p2, long double default_second){
          int parens = 0;
          size_t pos = 0;
          while(exp[pos]){
      	   switch (exp[pos]){
      		  case '(':
      			 parens++;
      			 break;
      		  case ')':
      			 parens--;
      			 break;
      		  case ',':
      			 if (!parens){
      				p1 = ToNumber(math(exp.substr(0, pos)));
      				p2 = ToNumber(math(exp.substr(pos + 1)));
      				return;
      			 }
      			 break;
      	   }
      	   pos++;
          }
          p1 = ToNumber(math(exp));
          p2 = default_second;
      }
      
      void math_constants(string & res){
          string constants[] = {"Pi", "pi", "PI"};
          for (unsigned int i = 0; i < 3; ++i){
      	   size_t pos = 0;
      	   while(true){
      		  pos = res.find(constants[i], pos);
      		  if (pos == string::npos) break;
      		  string side1 = res.substr(0, pos);
      		  string side2 = res.substr(pos + 2);
      		  res = side1 + pi_string + side2;
      		  pos += string(pi_string).length();
      	   }
          }
          size_t pos = 0;
          while(true){
      	   pos = res.find('e', pos);
      	   if (pos == string::npos) break;
      	   bool e_constant = true;
      	   // Wait!  Could be scientific notation or a function
      	   if (pos != 0){
      		  char c = res[pos-1];
      		  string digits("01234567890scp");
      		  if (digits.find_first_of(c) != string::npos) e_constant = false;
      	   }
      	   if ((e_constant) && (pos != res.length() - 1)){
      		  char c = res[pos-1];
      		  string digits("01234567890-scp");
      		  if (digits.find_first_of(c) != string::npos) e_constant = false;
      	   }
      	   if (e_constant){
      		  string side1 = res.substr(0, pos);
      		  string side2 = res.substr(pos + 1);
      		  res = side1 + e_string + side2;
      		  pos += string(pi_string).length();
      	   } else {
      		  pos++;
      	   }
          }
      }
      
      string math_operations_one(const string & exp){
          string ress(exp);
          ress = DoubleNegatives(ress);
          string funcs[] = {
      	   "asinh",  "acosh",  "atanh",  "asech", "acsch" , "acoth",
      	   "sinh" ,  "cosh" ,  "tanh" ,  "sech" , "csch"  , "coth" ,
      	   "asin" ,  "acos" ,  "atan2",  "atan" ,  "asec" , "acsc" ,   "acot",
      	   "sin"  ,  "cos"  ,  "tan"  ,  "sec"  , "csc"   , "cot" , 
      	   "logn" ,  "root" ,  "nPr"  ,  "nCr"  , "lambda", "hyper", "slog", "pow",
      	   "ln"   ,  "log"  ,  "sqrt" ,  "abs"  , "ceil"  , "floor", "round",
              "asum"};
          size_t pos = ress.find('(');
          size_t pos2 = math_paren(ress, pos);
          if (pos2 == string::npos) return "nan";
          string side1 = ress.substr(0, pos);
          CheckForFunction(side1, true);
          string side2 = ress.substr(pos2 + 1);
          CheckForFunction(side2, false);
          string inside = ress.substr(pos + 1, pos2 - pos - 1);
          bool indegrees = true;
          if (inside.length() > 3){
      	   if (inside.substr(inside.length() - 3) == "rad"){
      		  inside = inside.substr(0, inside.length() - 3);
      		  indegrees = false;
      	   }
          }
          inside = math(inside);
          unsigned int function = 0xFFFF;
          for (unsigned int i = 0; i < 41; ++i){
      	   int ppos = pos - funcs[i].length();
      	   if (ppos >= 0){
      		  if (side1.substr(ppos) == funcs[i]){
      			 function = i;
      			 side1 = side1.substr(0, side1.length() - funcs[i].length());
      			 break;
      		  }
      	   }
          }
          if (function == 0xFFFF){
      	   return side1 + inside + side2;
          }
          long double value = ToNumber(inside);
          
          long double degrees = (indegrees) ? value / 57.2957795f : value;
          long double res;
          switch (function){
      	   /*
      		  Inverse Hyperbolic Trig Functions
      	   */
      	   case 0:  //asinh
      		  res = log(value + sqrt((value * value) + 1.0f));
      		  return side1 + ToString(res) + side2;
      	   case 1:  //acosh
      		  if (value > 1.0f) return side1 + "nan" + side2;
      		  res = log(value + sqrt((value * value) - 1.0f));
      		  return side1 + ToString(res) + side2;
      	   case 2:  //atanh
      		  if (value <= 1.0f) return side1 + "nan" + side2;
      		  res = 0.5f * log((1.0f + value) / (1.0f - value));
      		  return side1 + ToString(res) + side2;
      	   case 3:  //asech
      		  if ((value <= 0) || (value > 1)) return side1 + "nan" + side2;
      		  res = log((1.0f + sqrt(1.0f - value * value)) / value);
      		  return side1 + ToString(res) + side2;
      	   case 4:  //acsch
      		  res = log((1.0f / value) + (sqrt(1.0f + value * value) / fabs(value)));
      		  return side1 + ToString(res) + side2;
      	   case 5:  //acoth
      		  if (fabs(value <= 1)) return side1 + "nan" + side2;
      		  res = 0.5f * log((value + 1.0f) / (value - 1.0f));
      		  return side1 + ToString(res) + side2;
      	   /*
      		  Hyperbolic Trig Functions
      	   */
      	   case 6:  //sinh
      		  return side1 + ToString(sinh(degrees)) + side2;
      	   case 7:  //cosh
      		  return side1 + ToString(cosh(degrees)) + side2;
      	   case 8:  //tanh
      		  return side1 + ToString(tanh(degrees)) + side2;
      	   case 9:  //sech
      		  return side1 + ToString(1.0f / cosh(degrees)) + side2;
      	   case 10:  //csch
      		  return side1 + ToString(1.0f / sinh(degrees)) + side2;
      	   case 11:  //coth
      		  return side1 + ToString(cosh(degrees) / sinh(degrees)) + side2;
      	   /*
      		  Inverse Trig Functions
      	   */
      	   case 12:  //asin
      		  return side1 + ToString(asin(value)) + side2;
      	   case 13:  //acos
      		  return side1 + ToString(acos(value)) + side2;
      	   case 14:  //atan2
          		  long double p1, p2;
      		  Split(inside, p1, p2, 1);
      		  return side1 + ToString(atan2(p1, p2)) + side2;
      	   case 15:  //atan
      		  return side1 + ToString(atan(value)) + side2;
      	   case 16:  //asec
      		  return side1 + ToString(1.0f / acos(value)) + side2;
      	   case 17:  //acsc
      		  return side1 + ToString(1.0f / asin(value)) + side2;
      	   case 18:  //atan
      		  return side1 + ToString(acos(value) / asin(value)) + side2;
      	   /*
      		   Trig Functions
      	   */
      	   case 19:  //sin
      		  return side1 + ToString(sin(degrees)) + side2;
      	   case 20:  //cos
      		  return side1 + ToString(cos(degrees)) + side2;
      	   case 21:  //tan
      		  return side1 + ToString(tan(degrees)) + side2;
      	   case 22:  //sec
      		  return side1 + ToString(1.0f / cos(degrees)) + side2;
      	   case 23:  //csc
      		  return side1 + ToString(1.0f / sin(degrees)) + side2;
      	   case 24:  //cot
      		  return side1 + ToString(cos(degrees) / sin(degrees)) + side2;
      	   /*
      		  Two parameter functions
      	   */
      	   case 25:{  //logn
      		  long double p1, p2;
      		  Split(inside, p1, p2, 1);
      		  return side1 + ToString(logn(p1, p2)) + side2;}
      	   case 26:{  //root
      		  long double p1, p2;
      		  Split(inside, p1, p2, 1);
      		  return side1 + ToString(pow(p1, 1.0f / p2)) + side2;}
      	   case 27:{  //nPr
      		  long double p1, p2, res;
      		  Split(inside, p1, p2, 1);
      		  int n = (int)p1;
      		  int r = (int)p2;
      		  res = (Factorial(r) / Factorial(n - r));
      		  return side1 + ToString(res) + side2;}
          	   case 28:{  //nCr
      		  long double p1, p2, res;
      		  Split(inside, p1, p2, 1);
      		  int n = (int)p1;
      		  int r = (int)p2;
      		  res = (Factorial(r) / (Factorial(r) * Factorial(n - r)));
      		  return side1 + ToString(res) + side2;}
      	   case 29:{  //lambda
      		  long double x, b;
      		  Split(inside, x, b, 1);
      		  return side1 + ToString(pow(x, pow(x, b - 1))) + side2;}
      	   case 30:{  //hyper
      		  long double a, x, res;
      		  Split(inside, a, x, 1);
      		  return side1 + ToString(hyper(a, x)) + side2;}
      	   case 31:{  //slog
      		  long double z, b, res;
      		  Split(inside, z, b, 1);
      		  return side1 + ToString(slog(z, b)) + side2;}
      	   case 32:{  //pow
      		  long double a, x, res;
      		  Split(inside, a, x, 1);
      		  return side1 + ToString(pow(a, x)) + side2;}
      		  
      	   /*
      		  The rest
      	   */
      	   case 33:  //ln
      		  return side1 + ToString(log(value)) + side2;
      	   case 34:  //log
      		  return side1 + ToString(log10(value)) + side2;
      	   case 35:  //sqrt
      		  return side1 + ToString(sqrt(value)) + side2;
      	   case 36:  //abs
      		  return side1 + ToString(fabs(value)) + side2;
      	   case 37:  //ceil
      		  return side1 + ToString(ceil(value)) + side2;
      	   case 38:  //floor
      		  return side1 + ToString(floor(value)) + side2;
      	   case 39:  //round
      		  return side1 + ToString((long double)((int)(value))) + side2;
      	   case 40:  //asum
      		  int n = (int)value;
      		  int res = 0;
      		  if (n % 2) res += n--;
      		  res += (n + 1) * (n >> 1);
      		  return side1 + ToString((long double)res) + side2;
          }
          return side1 + inside + side2;
      }
      
      long double GetLastNumber(string & exp){
          //this also strips it from the expression
          size_t pos = exp.find_last_not_of(" 0123456789ABCDEF.xe");  //e is okay here as scientific notiation, because of the first pass, e can not be directly next to a number
          if (pos == string::npos){
      	   long double res = ToNumber(exp);
      	   exp = "";
      	   return res;
          }
          string funcs("<>%^*/+");
          if (exp[pos] == '-'){  //dammit, it this a negation or a subtraction
      	   if (pos == 0){  //has to be a negation
      		  long double res = ToNumber(exp);
      		  exp = "";
      		  return res;
      	   }
      	   if (exp[pos - 1] == 'e'){  //negative scientific notation
      		  size_t nextpos = exp.find_last_not_of("0123456789.", pos - 2);  //scientific notation can only have these characters
      		  if (nextpos == string::npos){
      			 long double res = ToNumber(exp);
      			 exp = "";
      			 return res;
      		  }
      		  if (exp[nextpos] == '-'){  //dammit, it this a negation or a subtraction
      			 if (nextpos == 0){  //has to be a negation
      				long double res = ToNumber(exp);
      				exp = "";
      				return res;
      			 }
      		  }
      		  pos = nextpos;
      	   }
      	   int number_of_minuses = 1;
      	   long double res = ToNumber(exp.substr(pos + 1)); 
      	   string temp = exp.substr(0, pos);
      	   size_t previous = temp.find_last_not_of(' ', pos - 2);
      	   if (previous == string::npos){  //must be a negative
      		  if (number_of_minuses % 2) res *= -1.0f;
      		  exp = "";
      		  return res;
      	   }
      	   char c = exp[previous];
      	   if (funcs.find_first_of(c) != string::npos){  //there is another function before it, it must be negation
      		  pos--;
      	   }
          } else if (exp[pos] == '+'){
      	   if (exp[pos - 1] == 'e'){
      		  size_t nextpos = exp.find_last_not_of("0123456789.", pos - 2);  //scientific notation can only have these characters
      		  if (nextpos == string::npos){
      			 long double res = ToNumber(exp);
      			 exp = "";
      			 return res;
      		  }
      		  pos = nextpos;
      	   }
          } else if (exp[pos] == 'y'){
      	   exp = exp.substr(0, pos - 7);
      	   pos = exp.find_last_not_of(' ');
      	   if (pos == string::npos) return 1.0f/0.0f;
      	   if (exp[pos] == '-'){  //negative infinity or subtraction?
      		  if (pos == 0){  //has to be a negation
      			 long double res = 1.0f/0.0f;
      			 exp = "";
      			 return res;
      		  } 
      	   }
      	   string temp = exp.substr(0, pos);
      	   size_t previous = temp.find_last_not_of(' ');
      	   if (previous == string::npos){  //must be a negative
      		  long double res = -1.0f/0.0f;  
      		  exp = "";
      		  return res;
      	   }
      	   char c = exp[previous];
      	   if (funcs.find_first_of(c) != string::npos){  //there is another function before it, it must be negation
      		  long double res = -1.0f/0.0f;  
      		  exp = "";
      		  return res;
      	   }
      	   return 1.0f/0.0f;
          } else if ((exp[pos] == 'n') && (exp[pos - 1] == 'a') && (exp[pos - 2] == 'n')){
      	   exp = exp.substr(0, pos - 2);
      	   return sqrt(-1);
          }
          string num = exp.substr(pos + 1);
          cout << num << endl;
          exp = exp.substr(0, pos + 1);
          return ToNumber(num);
      }
      
      long double GetFirstNumber(string & exp){
          //this also strips it from the expression
          size_t pos = exp.find_first_not_of(" 0123456789ABCDEF.xe");  //e is okay here as scientific notiation, because of the first pass, e can not be directly next to a number
          if (pos == string::npos){
      	   long double res = ToNumber(exp);
      	   exp = "";
      	   return res;
          }
          string funcs("<>%^*/+-");
          if (exp[pos] == '-'){  //dammit, it this a negation or a subtraction
      	   if (exp[pos + 1] == 'I'){  //-Infinity
      		  exp = exp.substr(pos + 9);
      		  return -1.0f/0.0f;
      	   }
      	   if (pos == 0){  //has to be a negation
      		  long double res = ToNumber(exp);
      		  exp = "";
      		  return res;
      	   }
      	   if (exp[pos - 1] == 'e'){  //negative scientific notation
      		  size_t nextpos = exp.find_first_not_of("0123456789.", pos + 1);  //scientific notation can only have these characters
      		  if (nextpos == string::npos){
      			 long double res = ToNumber(exp);
      			 exp = "";
      			 return res;
      		  }
      		  pos = nextpos;
      	   }
      	   string temp = exp.substr(pos);
      	   size_t next = temp.find_first_not_of(' ');
      	   if (next == string::npos){  //must be a negative
      		  long double res = ToNumber(exp.substr(pos));  
      		  exp = "";
      		  return res;
      	   }
      	   char c = exp[next];
      	   if (funcs.find_first_of(c) != string::npos){  //there is another function before it, it must be negation
      		  pos--;
      	   }
          } else if (exp[pos] == '+'){
      	   if (exp[pos - 1] == 'e'){
      		  size_t nextpos = exp.find_first_not_of("0123456789.", pos + 1);  //scientific notation can only have these characters
      		  if (nextpos == string::npos){
      			 long double res = ToNumber(exp);
      			 exp = "";
      			 return res;
      		  }
      		  pos = nextpos;
      	   }
          } else if (exp[pos] == 'I'){  //Infinity
      	   exp = exp.substr(pos + 8);
      	   return 1.0f/0.0f;
          } else if ((exp[pos] == 'n') && (exp[pos + 1] == 'a') && (exp[pos + 2] == 'n')){
      	   exp = exp.substr(pos + 3);
      	   return sqrt(-1);
          }
          string num = exp.substr(0, pos);
          exp = exp.substr(pos);
          return ToNumber(num);
      }
      
      string math_operations_two(const string & exp){
          /*
      	   ! (factorial)
          */
          string res(exp);
          res = DoubleNegatives(res);
          size_t pos = res.find('!');
          string side1 = res.substr(0, pos);
          string side2 = res.substr(pos + 1);
          int result = (int)GetLastNumber(side1);
          /*
      	   GetLastNumber will include a negation if there is one, but negation has lower order precedence
      	   than factorial, so I need to strip it and readd it later.
          */
          if (result < 0){ //strip the negative and put it on side1
      	   side1 += "-";
      	   result *= -1;
          }
          return side1 + ToString(Factorial(result)) + side2;
      }
      
      string math_operations_three(const string & exp){
          /*
      	   * 
      	   / 
      	   ^ 
      	   \
          */
          string res(exp);
          res = DoubleNegatives(res);
          
          size_t pos = res.find_first_of("*/^\\");
          string side1 = res.substr(0, pos);
          string side2 = res.substr(pos + 1);
          switch(res[pos]){
      	   case '*':{
      		  long double aa = GetLastNumber(side1);
      		  long double bb = GetFirstNumber(side2);
      		  return side1 + ToString(aa * bb) + side2;}
      	   case '/':{
      		  long double aa = GetLastNumber(side1);
      		  long double bb = GetFirstNumber(side2);
      		  return side1 + ToString(aa / bb) + side2;}
      	   case '\\':{
      		  int aa = (int)GetLastNumber(side1);
      		  int bb = (int)GetFirstNumber(side2);
      		  return side1 + ToString((long double)(aa / bb)) + side2;}
      	   case '^':{
      		  long double aa = GetLastNumber(side1);
      		  long double bb = GetFirstNumber(side2);
      		  return side1 + ToString(pow(aa, bb)) + side2;}
          }
          return res;
      }
      
      string math_operations_four(const string & exp, bool & true_pos){
          /*
      	   +
      	   -
      	   % : modulus
          */
          string res(exp);
          res = DoubleNegatives(res);
          size_t pos = res.find_first_of("+-%");
          /*
      	   Check for scientific notation and negations
          */
          if ((res[pos] == '+') && (res[pos - 1] == 'e')){
      	   pos = res.find_first_of("+-%", pos + 1);
      	   if (pos == string::npos){
      		  true_pos = false;
      		  return res;
      	   }
          }
          if (res[pos] == '-'){
      	   if (pos == 0){  //obviously a negation
      		  pos = res.find_first_of("+-%", 1);
      		  if (pos == string::npos){
      			 true_pos = false;
      			 return res;
      		  }
      	   }
      	   if (res[pos - 1] == 'e'){
      		  pos = res.find_first_of("+-%", pos + 1);
      		  if (pos == string::npos){
      			 true_pos = false;
      			 return res;
      		  }
      	   }
          }
          
          
          
          string side1 = res.substr(0, pos);
          string side2 = res.substr(pos + 1);
          switch(res[pos]){
      	   case '+':{
      		  long double aa = GetLastNumber(side1);
      		  long double bb = GetFirstNumber(side2);
      		  return side1 + ToString(aa + bb) + side2;}
      	   case '-':{
      		  long double aa = GetLastNumber(side1);
      		  long double bb = GetFirstNumber(side2);
      		  return side1 + ToString(aa - bb) + side2;}
      	   case '%':{
      		  int aa = (int)GetLastNumber(side1);
      		  int bb = (int)GetFirstNumber(side2);
      		  return side1 + ToString((long double)(aa % bb)) + side2;}
          }
          return res;
      }
      
      string math_operations_five(const string & exp){
          /*
      	   <<
      	   >>
          */
          string res(exp);
          res = DoubleNegatives(res);
          size_t pos = res.find("<<");
          if (pos == string::npos) pos = res.find(">>");
          string side1 = res.substr(0, pos);
          string side2 = res.substr(pos + 2);
          switch(res[pos]){
      	   case '<':{
      		  int aa = (int)GetLastNumber(side1);
      		  int bb = (int)GetFirstNumber(side2);
      		  return side1 + ToString((long double)(aa << bb)) + side2;}
      	   case '>':{
      		  int aa = (int)GetLastNumber(side1);
      		  int bb = (int)GetFirstNumber(side2);
      		  return side1 + ToString((long double)(aa >> bb)) + side2;}
          }
          return res;
      }
      
      string StripWhiteSpace(const string & exp){
          stringstream out;
          size_t pos = 0;
          char c = exp[pos++];
          while(c){
      	   if (c != ' ') out << c;
      	   c = exp[pos++];
          }
          return out.str();
      }
      
      string math(const string & exp){
          string res(exp);
          res = StripWhiteSpace(res);
          math_constants(res);  
          while(res.find('(') != string::npos) res = math_operations_one(res);
          while(res.find('!') != string::npos) res = math_operations_two(res);
          while(res.find_first_of("*/^\\") != string::npos) res = math_operations_three(res);
          bool true_pos = true;
          while((res.find_first_of("+-%") != string::npos) && (true_pos)) res = math_operations_four(res, true_pos);
          while((res.find("<<") != string::npos) || (res.find(">>") != string::npos)) res = math_operations_five(res);    
          return res;
      }
      
      #define Check(func, ans);\
          cout << ((math(func) == #ans) ? "Passed" : string("Failed: \"") + func + "\" != " + #ans + ", it's " + math(func)) << endl;
      
      int main (int argc, char * const argv[]) {
          // insert code here...
          Check("2(4(2) + 1)"				, 18);
          Check("sqrt(52 * (50 + 2))"		, 52);
          Check("1+1 << 4"				, 32);
          Check("abs(70 - (ceil(2.2) * 25))"	, 5);
          Check("1e+2 + 1e2 - 10e-1"		, 199);
          Check("4.5/2 + ln(e)"			, 3.25);
          Check("4.5\\2"					, 2);
          Check("24%5"					, 4);
          Check("5 + -(4/2)"				, 3);
          Check("1/0"					, Infinity);
          Check("Pi + -Infinity"			, -Infinity);
          Check("12 + nan * 25"			, nan);
          Check("15 * sqrt(-1)"			, nan);
          Check("asum(1e+2)"				, 5050);
          Check("--1"					, 1);
          Check("-sqrt(144)"				, -12);
          
          return 0;
      }
      Last edited by ninja9578; 08-10-2009 at 01:26 PM.

    Bookmarks

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •