Hi, so i'm working on this project and i seem to keep getting a number off what it should be. I believe my problem lies in the eval function but i'm not sure. The program compiles and runs but the output is off. Any help would be great. Thanks
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
double eval(Tree *root)
{
// for (recursively) evaluating a tree; this function will refer
// back to itself (for evaluating subtrees) and will use the
// evalOp() functions
double result;
if(root->op != "")
{
if(root->right == NULL) result = evalOp(root->op, eval(root->left));
else result = evalOp(root->op, eval(root->left), eval(root->right));
}
return result;
}
You haven't shown us the declaration for Tree, nor evalOp (2 argument and 3 argument versions).
From what I see, there is an implicit assumption that root->left is never null.
If root->left can be null, then the above code is going to have problems.
#include <iostream>
#include <string>
#include <cmath>
#include "math_tree.h"
#include "calc_parser.h"
usingnamespace std;
double evalOp(string op, double val)
{
// for evaluating functions like sin, cos, etc.
double result;
if(op == "sin") result = sin(val);
if(op == "cos") result = cos(val);
if(op == "tan") result = tan(val);
if(op == "log") result = log(val);
if(op == "abs") result = abs(val);
return result;
}
double evalOp(string op, double val1, double val2)
{
// for evaluating operators like +, -, etc.
double result = 0;
if(op == "+") result = val1+val2;
if(op == "-") result = val1-val2;
if(op == "/") result = val1/val2;
if(op == "*") result = val1*val2;
if(op == "^") result = pow(val1, val2);
return result;
}
double eval(Tree *root)
{
// for (recursively) evaluating a tree; this function will refer
// back to itself (for evaluating subtrees) and will use the
// evalOp() functions
double result;
if(root->op != "")
{
if(root->right == NULL) result = evalOp(root->op, eval(root->left));
else result = evalOp(root->op, eval(root->left), eval(root->right));
}
return result;
}
// this is a global variable used by the parser
Tree* math_tree;
int main()
{
// hand-code a tree for this expression:
// sin(3.14159/4.0)+cos(8.0*2.0)
Tree p1;
p1.op = "+";
Tree p2;
p2.op = "sin";
Tree p3;
p3.op = "cos";
Tree p4;
p4.op = "/";
Tree p5;
p5.op = "*";
Tree v1;
v1.val = 3.145159;
Tree v2;
v2.val = 4.0;
Tree v3;
v3.val = 8.0;
Tree v4;
v4.val = 2.0;
p1.left = &p2;
p1.right = &p3;
p2.left = &p4;
p2.right = NULL;
p3.left = &p5;
p3.right = NULL;
p5.left = &v3;
p5.right = &v4;
p4.left = &v1;
p4.right = &v2;
v1.left = v1.right = v2.left = v2.right = v3.left = v3.right = v4.left = v4.right = NULL;
// here we print your hand-coded tree
print_ascii_tree(&p1);
// and evaluate the hand-coded tree (should equal -0.25)
cout << "Result: " << eval(&p1) << endl << endl << endl;
// this is the user-input loop; there is no need to change it
while(true)
{
Parser parser;
cout << "Enter expression: ";
// this function gets the input and does the parsing
parser.yyparse();
// the yyparse() function sets the global variable math_tree
// to a new tree; if that tree is NULL (no tree), just quit
if(math_tree == NULL)
break;
// otherwise, print the tree
print_ascii_tree(math_tree);
// and evaluate it
cout << "Result: " << eval(math_tree) << endl << endl;
// reset the tree back to NULL before looping
math_tree = NULL;
}
return 0;
}
Line 81: You set v1-v4 left and right to null. That makes sense, but as I pointed out earlier, if left is null in any node that is going to cause a problem.
Line 40-41: Consider what happens when when root->left is null. You call eval() with a null pointer. eval() contains no check for a null pointer. It just assumes it was passed a valid pointer.