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] 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? ------------------------------------------------------------------------ [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