in reply to Decimal Arithmetic

Hi gcoates,

Depending on what you're trying to do, the built-in math functions in Perl should in most cases be fine for financial calculations, I would think.

And no library is going to give you exact calculations, so if you're searching for something that's 100% accurate, you won't ever find it; there's always an example where normal rounding will cause errors to creep in.

Can you provide an example of what kind of thing you're looking for?


s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/

Replies are listed 'Best First'.
Re^2: Decimal Arithmetic
by ikegami (Patriarch) on Feb 05, 2007 at 22:25 UTC

    And no library is going to give you exact calculations

    Why not? If you're just going to use the basic operators (+-/*%), then you can store any number precisely as a fraction of arbitrarily large integers.

          you can store any number precisely as a fraction of arbitrarily large integers

      Okay, how would you store pi precisely as a fraction of arbitrarily large integers?  How about the square root of 2?  Or e?

      My point is, unless you're using unlimited storage, there's always a potential for round-off to occur.  It may be very, very miniscule round-off, and it may not affect monetary calculations, but you've always got the potential for introducing such errors, depending on what operations you're performing.


      s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/

        I don't remember the last time I owed π dollars to someone. Remember, you are starting with finite amounts (fractions of cents), not numbers like π.

        There not always a potential for round-off to occur, when the system has bounds. When something is 1/3rd off, the discount will be rounded/ceiled/floored. Infinite precision is not needed.

Re^2: Decimal Arithmetic
by gcoates (Novice) on Feb 05, 2007 at 22:39 UTC
    The place I'm having problems is with invoices in accounts payable. Each invoice I'm recording can have an arbitrary number of items that are purchased. Each invoice can also have a tax amount and a shipping/handling amount. The shipping and tax amounts need to be distributed to the accounts in which the invoice items are recorded. When I try to split these amounts, I'm getting rounding errors. (I'm using the Math::BigFloat library with an accuracy of 17 digits and a precision of 5 decimal places for my calculations.) Does this seem reasonable?
      When I try to split these amounts, I'm getting rounding errors.

      This sounds more like a business logic problem than a decimal precision problem.

      For example, I have $1.00 that I need to allocate out to 3 parties. If I just divide by 3 and round to the nearest penny, then everyone pays $0.33 and I'm short a penny.

      -xdg

      Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

      Splitting an invoice's lot-shipping charge so that it may be charged to accounts associated with specific line items is a task usually left to human judgement. There is no reason to imagine that
      • items belong to the same freight-rate class,
      • items are shipped from the same location,
      • an item's shipping weight is consistent
      Aside from the above, freight may be put into the cost of the line items or to a general ledger account, like Inbound Freight; how formally this policy is determined can vary.

      All of which is just to say: Ouch!

      Be well,
      rir

      5 decimal places precision

      It certainly seems reasonable to me, if you are calcuating to pennies. To be on the safe side, you could always round up/down (to the nearest penny) in favor of the customer. You could absorb the penny/per cost and raise your rate by a penny :-). If you need more accuracy, look at xs outputs faster than perl can keep up and use MPFR to as many decimal places of precision you want.


      I'm not really a human, but I play one on earth. Cogito ergo sum a bum
      This is purely a design problem. Why do you have a price for each item, but only a total tax for the invoice? Why not have a price for each item, a tax for each item, and a S&H for each item? Then, you aggregate those as the total tax and total S&H for the invoice.

      If, as I suspect, the S&H won't be amenable to that kind of breakout, then that's where your business problem arises.


      My criteria for good software:
      1. Does it work?
      2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?