简体   繁体   中英

PHP money calculation precision

I have a project that stores money as bigint column in a database (storing in cents). I'm planning to rewrite this thing to use BCMATH instead. I don't mind integers, but they give me some terrible rounding errors event stored in cents and I suspect I might have the same rounding errors in BCMATH. The problem arises in situations, like in this pseudocode:

$price = $some_price_in_cents * $store_price_increase; // second value is a float for final price calculation, so the result might have fractions of a cent
$price_total = $price * $qty;
$discount = // some discount in cents (might have fractions of a cent)
$discount *= $qty;
$discounted_price = $price_total - $discount;

When inserting into a database, I do round() on all values in cents. And now I have a record which says:

total price = 12134
discount = 460
discounted price = 11675

Now if I do 12134 - 460 ... I obviously get 11674 and not 11675. I also suspect that if I changed the way things are calculated (eg. multiply everything by the QTY at the end), I'd get even different results.

Would I get this kind of behaviour using BCMATH? Would the result depend on the order of math operations? How would I properly calculate the above using BCMATH and store it in DB (assuming 2 decimal places are required)?

I believe this is what you need. Note that bcmath requires strings. The number 2 is to specify how many decimals you need.

$price = bcmul($some_price_in_cents, $store_price_increase, 2);
$price_total = bcmul($price, $qty, 2);
$discount = bcmul($qty, "discount amount", 2);
$discounted_price = bcsub($price_total, $discount, 2);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM