🔒 Locked
Coding a calculator
Advertisement
Original Post
C++ (and pretty much every other programming language) will perform the order of operations properly when evaluating a mathematical expression, so as long as you follow the order of operations in your code, you should be fine.
Quote:
Original post by programwizard
C++ (and pretty much every other programming language) will perform the order of operations properly when evaluating a mathematical expression, so as long as you follow the order of operations in your code, you should be fine.
He won't use the standard C++ functions or operators when he recieves the data at runtime.
The answer to the original question depends on how you want to recieve input for example if you just retrieve a text string you could easily set up a tree like this:
1+2*3:4+5
+ / \ 1 + / \ : 5 / \ * 4/ \ 2 3I hope my tree can be read.
It shouldn't be so hard to produce rules for operator precedence.
EDIT: Fixed the tree
I'm not talking about how the compiler does the work, I'm talking about how one might implement their own calculator that handles this stuff.
For example, consider the input of
2-45*23/8+22
as a string or something, and you wanted to calculate the result of this. Ignoring the parsing to get the numbers and operators out, what is the typical process of getting the proper output? I think I read of a process before that was the typical method of doing this but I don't remember the term.
Edit: That's more what I'm talking about, thanks CTar
For example, consider the input of
2-45*23/8+22
as a string or something, and you wanted to calculate the result of this. Ignoring the parsing to get the numbers and operators out, what is the typical process of getting the proper output? I think I read of a process before that was the typical method of doing this but I don't remember the term.
Edit: That's more what I'm talking about, thanks CTar
Depends on the order of operations.
A reverse-polish (aka prefix) notation calculator that can evaluate arbitrary expressions (such as (+ 48 36 (* 12 19)) is easy to write. An infix-notation expression evaluator is slightly more difficult, but still possible.
Of course, that's if what you actually want is an expression evaluator. If you want something like a typical pocket calculator (or Windows calc), it's pretty easy - order of operations doesn't matter. You simply have a stored value (which usually takes the result of the last computation) and an entered value (the last number punched in), and the operation is performed on those two values. Of course, if you want more complex behavior like support for parenthetical subexpressions, you have to have a stack-based context that lets you push back calculations whenever a parenthetical starts, and so on.
So... upshot of all that? Step 1 is to decide what your features are. Figure out the software you want to make first; thus far the description you've posted is far too open-ended.
[edit] I am the slow.
Sounds like what you want is a basic scanner/parser system. Basically what you'll do is read the string and turn it into a list of tokens like "4" "374" and "*". Then, you'll use the order in which tokens appear, combined with precedence and associativity rules, to produce a tree like CTar's that represents the expression. From there it's a trivial matter of walking the tree from the bottom up and reducing each node until you simplify the root node, and that's your answer.
[edit again] In other news, I'm stupid. RPN and prefix notation are of course not the same. My example is of prefix notation (Lisp on the brain); there's a decent intro to RPN here.
A reverse-polish (aka prefix) notation calculator that can evaluate arbitrary expressions (such as (+ 48 36 (* 12 19)) is easy to write. An infix-notation expression evaluator is slightly more difficult, but still possible.
Of course, that's if what you actually want is an expression evaluator. If you want something like a typical pocket calculator (or Windows calc), it's pretty easy - order of operations doesn't matter. You simply have a stored value (which usually takes the result of the last computation) and an entered value (the last number punched in), and the operation is performed on those two values. Of course, if you want more complex behavior like support for parenthetical subexpressions, you have to have a stack-based context that lets you push back calculations whenever a parenthetical starts, and so on.
So... upshot of all that? Step 1 is to decide what your features are. Figure out the software you want to make first; thus far the description you've posted is far too open-ended.
[edit] I am the slow.
Sounds like what you want is a basic scanner/parser system. Basically what you'll do is read the string and turn it into a list of tokens like "4" "374" and "*". Then, you'll use the order in which tokens appear, combined with precedence and associativity rules, to produce a tree like CTar's that represents the expression. From there it's a trivial matter of walking the tree from the bottom up and reducing each node until you simplify the root node, and that's your answer.
[edit again] In other news, I'm stupid. RPN and prefix notation are of course not the same. My example is of prefix notation (Lisp on the brain); there's a decent intro to RPN here.
When I tried that a few years ago, I found that the easier(for me) procedure was to take from the user a normal expression and transform it internally into post-fix notation(the rules of how to do that are simple). Then, calculating a post-fix expression is very simple, all it really requires is a stack. You can even very easily translate it into FPU instructions.
Wow, the first two posters (EDIT: beaten many times; this originally said "you both") completely missed the point.
DrEvil, what you want to do is make use of a lexer (to tokenize the input and distinguish the numbers from the operators) and parser (to "take into account order of operations" and build a tree out of that list of input tokens, which can then be reparsed into a list of actions to take). Then you either interpret or compile based off of the parsed results (typically you produce a data structure called an abstract syntax tree (AST)):
DrEvil, what you want to do is make use of a lexer (to tokenize the input and distinguish the numbers from the operators) and parser (to "take into account order of operations" and build a tree out of that list of input tokens, which can then be reparsed into a list of actions to take). Then you either interpret or compile based off of the parsed results (typically you produce a data structure called an abstract syntax tree (AST)):
// We have an inheritance hierarchy:// node - constant_node// - operator_node - plus_node// - times_node// - sub_node// - div node// For example. Also, we have a virtual evaluate() member function,// with a virtual operate_on declared in operator_node which is a helper.// Interpretingtop_of_tree->evaluate();result_type operator_node::evaluate() { return operate_on(left->evaluate(), right->evaluate());}result_type plus_node::operate_on(result_type x, result_type y) { // For example. return x + y;}result_type constant_node::evaluate() { return m_value;}// compiling - in this case, we stream out some data in a very simple// stack-based assembly-like language.top_of_tree->emit_code();void operator_node::emit(ostream& os) { left->emit(os); right->emit(os); os << opcode() << std::endl;}const char* plus_node::opcode() { return "ADD";}void constant_node::emit(ostream& os) { os << "PUSH " << m_value << std::endl;}
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement