PHP 10.0 Blog

What if…

Making $$$ with PHP

Posted by Stas on March 31, 2007

Not exactly what you thought reading the title, sorry :) Just wanted to write about the topic discussed elsewhere – how one could do money calculations with PHP? PHP has no BCD type and no arbitrary precision float type either. And for money calculations is it important to have it very precise – accountants can not allow even single penny to slip by (remember the plot of the Office Space movie? ;)
So, using regular floats/doubles is not good in this case – for starters, there’s no precise representation for number as simple as 0.1! So if you make a lot of calculations with such numbers errors would creep in. Now the question is what could be done about it?

One solution is to make all calculations in units like one hundredth or thousandth of a cent and make everything integer, using arbitrary-precision integers like in GMP and then when printing it just shift the point and cut the extra digit whenever needed. This might be good enough if we knew how precise we should get.

Even better would be to have a type that combines arbitrary-precision integer and decimal point position, like Java does. I wonder if something can be done with GMP. It does have arbitrary precision floats, but I’m not sure it would fit.

Or, maybe there’s some other, better solutions for this? I don’t have much experience with money calculations and problems and solutions in that area…

About these ads

11 Responses to “Making $$$ with PHP”

  1. Ron said

    http://ca.php.net/manual/en/ref.bc.php

    BC math…

  2. When I read your ruminations, I immediately thought, “Money Object”! This description page gives the basic gist, you’d have to get your hands on a copy of the book to see the whole thing though.

    So, using regular floats/doubles is not good in this case

    Absolutely correct.

    One solution is to make all calculations in units like one hundredth or thousandth of a cent and make everything integer, using arbitrary-precision integers like in GMP and then when printing it just shift the point and cut the extra digit whenever needed.

    Instead of dividing money like a mathematician would, you want to “allocate” it. For example, say you have five cents you need to distribute to three people. A mathematician would say, “Oh, give each person 1 2/3 of a cent to each person.” But 2/3 of a cent doesn’t really make much sense. A more logical way of doing things is give two people two cents, and one person one cent.

    Of course, you’d be talking about big numbers, so it’s just a penny here and a penny there, but it still all adds up.

  3. I’ve written a couple of extensive financial libraries with PHP using BCMath.

    I usually have a method that sets the calculation precision using bcscale() – the higher the scale the lower the precision issues. Then I have a couple rounding functions which round the final calculated number back to the precision that the out put needs.

    This still isn’t exact (numbers do start to wander when you get down to thousandths of a percent) but it’s good enough for my needs.

  4. Rich Buggy said

    To implement currency you need to know who’s currency you’re implementing:
    US – Metric system with 2 decimal places
    Australia – Similar to the US but cash transactions are rounded to the nearest 0.05 at the end of the transaction
    Japan – I believe they use whole numbers

  5. fett said

    I’m using a Money object.

  6. Stas said

    Does bcmath solve the 0.1 problem? Docs on it are a bit scarce, so not sure if it does calculations in decimal or in binayr and how efficient is it, how rounding is done, etc.

  7. heggaton said

    Australia – Similar to the US but cash transactions are rounded to the nearest 0.05 at the end of the transaction

    Um, a bit more to it than that. It only occurs on *cash* transactions. On every other transaction, no rounding is performed.

    This is because, the $0.05 cent coin is the smallest coin in our currency.

    Using electronic means or credit card, a transaction of $3.57 not $3.55 will occur.

  8. PHP 10.0 Blog: Making $$$ with PHP

  9. [...] a brieft post to the PHP 10.0 Blog today, Stas looks at a topic several PHPers out there have had to struggle [...]

  10. cj said

    Some databases have arithmetic well suited for financial calculations. – and also for date calculations too. This can be very useful where accuracy matters but does mean thinking carefully about the PHP application architecture.

  11. ninware said

    the money_format function maybe usefull

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
Follow

Get every new post delivered to your Inbox.

%d bloggers like this: