Precision Math with PHP

by Expert ‎12-07-2010 10:50 AM - edited ‎10-20-2011 10:01 AM (18,076 Views)

One plus one equals two, right? How about .2 plus 1.4 times 10? That equals 16, right? Not if you're doing the math with PHP (or most other programming languages):

 

echo floor((0.2 + 1.4) * 10); // Should be 16. But it's 15!

 

This is due to how floating point numbers are handled internally. They are represented with a fixed number of decimal places and can result in numbers that do not add up quite like you expect. Internally our .2 plus 1.4 times 10 example computes to roughly 15.9999999998 or so. This kind of math is fine when working with numbers that do not have to be precise like percentages. But when working with money precision matters as a penny or a dollar missing here or there adds up quickly and no one likes being on the short end of any missing money.

 

The BC Math Solution

 

Fortunately PHP offers the BC Math extension which is "for arbitrary precision mathematics PHP offers the Binary Calculator which supports numbers of any size and precision, represented as strings." In other words, you can do precise math with monetary values using this extension. The BC Math extension contains Functions that allow you to perform the most common operations with precision including addition, subtraction, multiplication, and division.

 

A Better Example

 

Here's the same example as above but using the bcadd() function to do the math for us. It takes three parameters. The first two are the values we wish to add and the third is the number of decimal places we wish to be precise to. Since we're working with money we'll set the precision to be two decimal palces.

 

echo floor(bcadd('0.2', '1.4', 2) * 10); // It's 16 like we would expect it to be.

 

Conclusion

 

Using the BC Math extension is easy and allows us to precisely handle money transaction without rounding errors or any inaccuracies. Always use it when handling monetray transactions in your PHP application. If you're not using PHP, you may want to consider using the appropriate library for your programming language.

---------------------------------------------------------------------------------------------------


John Conde is a certified Authorize.Net developer

Comments
by
on ‎09-05-2011 08:25 AM

Sorry to ask stupid questions, but why are you using floor() instead of round() in the first place? It's bad practice to truncate your numbers when working with money, and rounding eliminates any problems you might have with being a few billionths off one way or the other.

by Expert
on ‎09-07-2011 06:01 AM
floor() was used to demonstrate how PHP handles precision math, particularly how it can lead to incorrect values. It wasn't meant to show how math should be done in an ecommerce environment.