Edit report at https://bugs.php.net/bug.php?id=65637&edit=1
ID: 65637
Comment by: productivepc at hotmail dot com
Reported by: productivepc at hotmail dot com
Summary: Using division PHP_ROUND_HALF_UP rounds DOWN when
working with 2 precision
Status: Feedback
Type: Bug
Package: Math related
Operating System: Windows 7
PHP Version: 5.5.3
Block user comment: N
Private report: N
New Comment:
In your example, you are rounding to 1 decimal place and yes absolutely that
will
throw it off however if you do =PRODUCT(ROUNDUP(1.45,2),1000) = 1450. I removed
all rounding except for the $additionalPcCostPerDay =
round($additionalPcCost/$totalWorkingDays,3,PHP_ROUND_HALF_UP); and the error
still happens. When I attempt to round to 2 decimal places the rounding
appears
to round down and not up. When I do it to 3 then it works as expected. It is
1:33am. I will write a smaller script tomorrow after I sleep and post it here.
Previous Comments:
------------------------------------------------------------------------
[2013-09-09 02:57:46] [email protected]
And by the way, you know that rounding numbers too early will throw off future
calculations, right? 1.45 * 1000 = 1450 but roundup(1.45, 1) * 1000 = 1500.
Don't
round until the very end.
------------------------------------------------------------------------
[2013-09-09 02:48:04] [email protected]
The script you've provided doesn't output the example numbers you gave. I get
additionalPcCostPerDay: 0.159 or 0.16
additionalPcProratedCost: 2.54 or 2.56
totalProratedCost: 131.34 or 131.36
Want to try the repro script again? Hopefully something a bit smaller with
fewer
variables?
------------------------------------------------------------------------
[2013-09-09 00:24:58] productivepc at hotmail dot com
Description:
------------
PHP Version 5.5.0
Results on Screen when precision is set to 2 for $additionalPcCostPerDay.
mainPcCost: 169
additionalPcCost: 3.3328571428571
WorkingDaysLeft: 16
totalWorkingDays: 21
mainPcCostPerDay: 8.05
additionalPcCostPerDay: 3.333
mainPcProratedCost: 128.8
additionalPcProratedCost: 53.33
totalProratedCost: 182.13
=============================================
Results on screen when I change the precision to 2. Please notice everything
has stayed the same but the totalProratedCost has changed.
contracttermid: 2
businesstypeid: 1
mainPcCost: 169
additionalPcCost: 3.3328571428571
WorkingDaysLeft: 16
totalWorkingDays: 21
mainPcCostPerDay: 8.05
additionalPcCostPerDay: 3.33
mainPcProratedCost: 128.8
additionalPcProratedCost: 53.28
totalProratedCost: 182.08
I noticed something because I have this same thing programmed in excel. I
decided to add the ROUNDUP function to my excel document just like I have it in
PHP to ensure that everything worked exactly the same and I noticed that when I
went to 2 decimals excel actually changed the additionalPcCostPerDay to 3.34
instead of keeping it 3.33 therefore raising the price to 182.24 and PHP
brought
the price down to 182.08 instead of keeping it 182.13. Looking in to this
further, if I use the ROUNDDOWN function
within excel then it too brings the price to 182.08 which is what makes me
believe that the PHP function PHP_ROUND_HALF_UP is actually ROUNDING DOWN
instead of UP. The
expected behavior for both excel and PHP would be to leave the price at 182.13.
When I use 3 decimals for both then both PHP and Excel agree that the
totalProratedPrice is 182.13. I am not sure if this is a bug however I wanted
to report it here before making a comment on the ROUND page with an example of
this.
The example below I do not have settype() in it however I have attempted this
by
changing everything over to a float with settype before I did any math and the
result was still the same.
Wayne
Test script:
---------------
$workingDaysLeft = 16;
$totalWorkingDays = 21;
$mainPcCost = 169;
$additionalPcCost = 3.3328571428571;
$mainPcCostPerDay = round($mainPcCost/$totalWorkingDays,2, PHP_ROUND_HALF_UP);
$additionalPcCost = $additionalPcCost/$totalWorkingDays;
// The next line is the problem area. When I change it to 2 precision the
expected behavior is for the total prorated cost to stay at 182.13 however it
drops to 182.08. If you change the below line to PHP_ROUND_HALF_DOWN then you
also get 182.08 which would indicate that the behavior is not behaving as
expected.
$additionalPcCostPerDay = round($additionalPcCost,3,PHP_ROUND_HALF_UP);
$mainPcProratedCost =
round($mainPcCostPerDay*$workingDaysLeft,2,PHP_ROUND_HALF_UP);
$additionalPcProratedCost =
round($additionalPcCostPerDay*$workingDaysLeft,2,PHP_ROUND_HALF_UP);
$totalProratedCost =
number_format($mainPcProratedCost+$additionalPcProratedCost,2,'.',',');
echo "<br>mainPcCost: " . $mainPcCost . "<br>additionalPcCost: " .
$additionalPcCost;
echo "<br>WorkingDaysLeft: " . $workingDaysLeft . "<br>totalWorkingDays: " .
$totalWorkingDays;
echo "<br>mainPcCostPerDay: " . $mainPcCostPerDay .
"<br>additionalPcCostPerDay: " . $additionalPcCostPerDay;
echo "<br>mainPcProratedCost: " . $mainPcProratedCost .
"<br>additionalPcProratedCost: " . $additionalPcProratedCost;
echo "<br>totalProratedCost: " . $totalProratedCost;
Expected result:
----------------
Whether I have precision for $additionalPcCostPerDay set to 2 or 3 the
totalProratedCost should remain the 182.13 and not change to 182.08.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=65637&edit=1