in reply to Re^2: Floating point problems
in thread Floating point problems

it seems to be an anti-pattern
No. It is not an anti-pattern here at all.

In fact is is the ONLY sensible thing to do.

That floats are not suitable to reprensent monetary amounts (ultimately because 0.1 is not a finite decimal in binary) is in fact so well known and has been so many times advised against that I am in fact surprised that anybody would consider this even for a second.

Replies are listed 'Best First'.
Re^4: Floating point problems
by bluescreen (Friar) on Oct 24, 2010 at 01:01 UTC

    Getting back to the Money example,

    Let say you have a multi-currency app (my case), so you have to deal with a wide range of exchange ratios ( i.e ARS exchange ratio is 0.252 ), now lets assume your money engine is written using cents and the price for one item is 1.10 ARS ( 110 ARS cents ) and you convert it to USD ( 25.452 USD cents ), if we just ignore the floating part of the amount your number becomes 0.25 USD ( 25 USD cents), when you convert it back to the orginal currency you get 0.99 ARS ( ~10% error )

    This situation is even worse than dealing floating point's error. And the more you need to do with the data the messier it becomes

      Seriously, if you have a multi currency application, consult with the people who actually know how to handle multiple currencies. They will tell you what the market convention is for calculating amounts. The ones I deal with usually calculate conversion rates to 6 fractional digits. Even if you came up with a more (mathematically) correct calculation, you'd still create differences because everyone else uses the market convention. So, talk to the people who know about the market conventions in your market about how to convert between currencies.

      If you're not dealing with cross-currency trading, converting back and forth between currencies will obviously introduce rounding errors. You can try to migitate these by using Math::BigRat as long as you only add/subtract/multiply/divide, but I really recommend doing all calculations in one currency and avoiding currency conversions up until the last step. Also see the part about "calculation of error" above - to minimize the introduction of errors through imprecision in the calculations, you'll need to reduce the number of such steps or arrange them in a way that they tend to cancel out each other.

      That's why Corion said: or thousandths of cents or whatever precision is needed

      You should analyze the calculations you are doing to determine the worst case accumulation of error. Based on this analysis you can choose a unit that is small enough that the accumulated error remains below your threshold of concern.