Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Re: Math 101 anyone?

by BrowserUk (Patriarch)
on Oct 12, 2004 at 08:10 UTC ( [id://398412]=note: print w/replies, xml ) Need Help??


in reply to Math 101 anyone?

...but when money is involved it needs to be 100% correct

If you store your currency as whole numbers of pennies/cents etc, then you will never get roundoffs and have total accuracy upto $/£/? 9 trillion (see machine accuracy).

For a simple explanation of why floating point doesn't give exact results, see Re: Re: Re: Bug? 1+1 != 2.


Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail
"Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon

Replies are listed 'Best First'.
Re^2: Math 101 anyone?
by bpphillips (Friar) on Oct 12, 2004 at 12:42 UTC
    Even using whole numbers, you still run into problems when you need to compute exchange rates or percent-off discounts. The company I work for has had to take a really close look at all of our rounding methods to make sure we don't have any pricing discrepancies.

      Once you move to storing your prices in pence/cents etc., and roundoff through division will be decimal pence/cents and it's usually ok to round these amounts up or down to the nearest whole pence/cents in favour of the customer without dramatically affecting your bottom line.

      The caveat is that you should accumulate all your sums and perform your discounting/exchange rate calculations on the total, not on each individual value prior to totalling.

      For example, if your customer is buying 10,000 widgets @ 10 pence each and is entitled to a 17.5% discount.

      $unitPrice = 10.0; $discount = 0.175; $units = 10_000; $totalPayable = int( $unitPrice * ( 1 - $discount ) * $units ); ## Cor +rect way printf "Total: £%.2f\n", $totalPayable / 100; ##Total: £825.00 $totalPayable = int( $unitPrice * ( 1 - $discount ) ) * $units; ## WRO +NG! printf "Total: £%.2f\n", $totalPayable / 100; ## Total: £800.00

      I once sat through a 3 hr long lecture on (UK) accounting conventions related to a very similar problem, the upshot of which was that you should always total up before applying any conversion that required division. The rules probably vary dependant upon where you live or pay taxes.


      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "Think for yourself!" - Abigail
      "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
        Unfortunately, in an e-commerce setting, you can't always wait until you have a total to show what the products will cost. You need to show the customer a price for one unit of a specific product (sometimes even with the discount broken out) in their own currency and then the numbers all need to add up to the correct total once they put several items into their cart. You end up getting penny off errors here and there that even if they are in favor of the customer, look very unprofessional.

        Our solution was the opposite of your suggestion. We determine the converted price of one unit of a specific item (including discounts and exchange conversions) before adding up the total because then we can count on it being consistent across the site and through the checkout process.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://398412]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (3)
As of 2024-04-26 06:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found