Monday 19 December 2016

PHP: Ceil function rounding issue




In one of my wordpress theme function, this code is being used to calculate total billable amount: ceil(($cost * (1 + ($charges / 100))) * 100);



There is a little miscalculation happening for below scenario.



Scenario:



$charges = 9;
$cost = 100;


echo ceil(($cost * (1 + ($charges / 100))) * 100);


The above code outputs 10901 whereas it should be 10900.



It works fine for other scenarios like:



$charges = 4;
$cost = 90.7;


echo ceil(($cost * (1 + ($charges / 100))) * 100);
//outputs 9433, which is fine because manual calculation results 9432.8


Question:




  1. Why is that happening?

  2. How can I prevent that?

  3. Any alternate function to round to next nearest integer? (only if amount is floating value)



Answer



The problem is that you are applying ceil to the outer expression. Try to rewrite it as:



$charges = 9;
$cost = 100;

echo ($cost + ceil($cost * $charges / 100)) * 100;



This outputs 10900 as expected.



UPDATE



As @cars10m suggested, simplifying the expression does help:



echo ceil($cost * 100  + $cost * $charges);


UPDATE 2




You can also use BCMath library to do precise math:



bcscale(6);
echo ceil(bcadd(bcmul($cost, 100), bcmul($cost, $charges)));

No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...