Edit report at https://bugs.php.net/bug.php?id=65637&edit=1
ID: 65637 User updated 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: Not a bug Type: Bug Package: Math related Operating System: Windows 7 PHP Version: 5.5.3 Block user comment: N Private report: N New Comment: Okay. Thanks for looking in to it. This can be closed. Previous Comments: ------------------------------------------------------------------------ [2013-09-09 06:59:03] requi...@php.net $additionalPcCostPerDay is either 3.33 (rounded to two) or 3.333 (rounded to three). The actual value is ~3.3328. The rounding there is correct. As for 0.05 drop, the difference "lost" using two decimal places is -0.003 * 16 = -0.048 and you round that off to -0.05. So that's where it came from. It sounds like you expect the rounding to carry from one number to the next? That's not how rounding works. That's why you always round at the very end of the set of calculations. ------------------------------------------------------------------------ [2013-09-09 05:49:28] productivepc at hotmail dot com I went ahead and wrote it before I went to bed. The only thing you have to change is the 3 to a 2 in this line: $additionalPcCostPerDay = round($additionalPcCost/$totalWorkingDays,3,PHP_ROUND_HALF_UP); You will see the price go from 182.09 when it is looking at 3 decimal places to 182.04 when it is looking at 2 decimal places. When rounding up even if the number previously was a 6 I would expect it to go to 182.10 and not drop $.05. <?php $workingDaysLeft = 16; $totalWorkingDays = 21; $mainPcCost = 169; $additionalPcCost = 69.99; $additionalpcs = 1; $mainPcCostPerDay = $mainPcCost/$totalWorkingDays; $additionalPcCostPerDay = round($additionalPcCost/$totalWorkingDays,3,PHP_ROUND_HALF_UP); $mainPcProratedCost = $mainPcCostPerDay*$workingDaysLeft; $additionalPcProratedCost = $additionalPcCostPerDay*$workingDaysLeft; $totalProratedCost = number_format($mainPcProratedCost+$additionalPcProratedCost,2,'.',','); $costPerFullMonth = $mainPcCost+($additionalpcs*$additionalPcCost); // echo "<br>mainPcCost: " . $mainPcCost . "<br>additionalPcCost: " . $additionalPcCost; // echo "<br>additionalpcs: " . $additionalpcs; // 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;// . " <br>costPerFullMonth: " . $costPerFullMonth; ?> ------------------------------------------------------------------------ [2013-09-09 05:34:34] productivepc at hotmail dot com 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. ------------------------------------------------------------------------ [2013-09-09 02:57:46] requi...@php.net 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] requi...@php.net 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? ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at https://bugs.php.net/bug.php?id=65637 -- Edit this bug report at https://bugs.php.net/bug.php?id=65637&edit=1