A few days ago, I had to need to evaluate mathamatical expressions entered by the users of the site. This could potentially cause security issue when using the PHP function eval(); so I decided to tackle the problem in a different way.
After some research, I came across a Eval Math by Miles Kaufmann. It has not been updated since 2005 and is slightly out of date. So I have decided to create a new open source project to create a better class.
As it is at the moment, initially I had no idea how to approach the problem. The first thing i needed to understand was how computers can evaluate mathematical expressions.
Eventually I came across infix notation and postfix notation. Only getting to A level Maths, I had no idea what they were. After battling through some heavy maths, I realised infix is the way we normally write expressions
Infix: 3 + 4 – 2
Postfix: 3 4 + 2 -
At first it looks odd but once explained it is simple. Here how it works:
- (3) is a number.
- (4) is another number
- (+) is an operation so take the previous 2 numbers (3 + 4 = 7).
So the expression becomes: 7 2 - - (7) is a number.
- (2) is a number.
- (-) is an operation so take the previous 2 numbers (7 – 2 = 5).
- Only one number left, that is the answer (5).
- So “3 + 4 – 2″ = “3 4 + 2 -” = 5
This is a simple example but the point is to make the expression easier for a computer to evaluate. Postfix removes the need for brackets in expression as precedence is sort by the order of the numbers and operations.
Few more examples:
Infix: -2 * (a + 5) + (-2 + 2)
Postfix: -2 a 5 + * -2 2 + +
Infix: 2a^2 + 2a + 2
Postfix: 2 a 2 ^ * 2 a * + 2 +
Once I understood this, I started writing an algorithm to convert infix to postfix using this wiki page http://en.wikipedia.org/wiki/Shunting-yard_algorithm.
Understanding the algorithm was alittle difficult at first but I eventually got my head around it.
And so I managed to get a working class that will evaluate math expressions.
The code is hosted at https://bitbucket.org/maca134/mathevaluator and anyone is welcome to contribute to the code.
At the moment the class will handle the following operations:
- Addition (+)
- Subtraction (-)
- Multiplication (*)
- Division (/)
- Power (^)
- Modulus (%)
- Parentheses
$results = MathEvaluator::e('2a + (12 / 2) - b * -2', array('a' => 2, 'b' => 4) ); array(4) { ["result"]=> float(18) ["infix"]=> string(22) "2a + (12 / 2) - b * -2" ["postfix"]=> string(23) "2 a * 12 2 / + b -2 * -" ["vars"]=> array(4) { ["a"]=> string(1) "2" ["b"]=> string(1) "4" } }
No related posts.







