Take the following example:
>>> from decimal import Decimal
>>> nrml_price = Decimal('0.59')
>>> discounted = nrml_price / 3 # Taking 2/3 off the price with a coupon
Decima开发者_如何转开发l('0.1966666666666666666666666667') # Customers don't have fractions of a penny
>>> (nrml_price / 3).quantize(D('0.00')) # So I quantize to get 2 decimal places
Decimal('0.20') # Ca fait combien? Cest vingt cents.
The problem is that I've now technically charged the customer for more than the expected price, albeit by less than 3/10 of a cent, but nonetheless it is technically incorrect.
How do I overcome a problem like this? Do I ignore it as a fact of life, or is there an accepted way to do this sort of thing (e.g. always charge the customer the nearest penny down)?
"is there an accepted way to do this sort of thing"
Yes. Accountants do it all the time.
Indeed COBOL does this really well.
The Python decimal
package has a bunch of rounding options that you set in the context. Almost always the decimal.ROUND_HALF_DOWN or decimal.ROUND_HALF_EVEN options are what you want in your context.
When building software for retail management like this, there will be corporate policies in place, managed by real accountants, which specify what should be done.
Ask the accountant who works with this line of business what the policy is.
The answer here may actually depend more on your transaction processor. Does your transaction processor allow you to transfer amounts of currency that are not whole numbers of cents? What about irrational value currency amounts? Say the discount was the square root of the normal price?
Most vendors (thats you here) will simply round up and keep the difference, in whole cents.
精彩评论