Evaluate Maths in PHP

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:

  1. (3) is a number.
  2. (4) is another number
  3. (+) is an operation so take the previous 2 numbers (3 + 4 = 7).
    So the expression becomes: 7 2 - 
  4. (7) is a number.
  5. (2) is a number.
  6. (-) is an operation so take the previous 2 numbers (7 – 2 = 5).
  7. Only one number left, that is the answer (5).
  8. 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
Here is an example of the code:
$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"
	}
}
Share and Enjoy:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks

No related posts.

This entry was posted in Blog. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">