Reputation: 13
I have created a PHP system that is having some problems with rounding. After looking further into this, I found that it goes back to the round function in PHP.
For instance...
Rounding 2047.615 to 2 decimal places gives 2047.62 (as expected)
Rounding 2048.615 to 2 decimal places gives 2048.61 (doesn't round up as expected)
I understand that the issue here most likely goes back to the inaccuracy of representing floating numbers in binary, but what is the most elegant way to take care of such issues?
Upvotes: 1
Views: 279
Reputation: 13
Here's the best solution I've come up with. In the following snippet I separate out the integer and decimal parts of the number and then do my rounding just on the decimal part (which gives me more bits available to work on the decimal accuracy). Does anybody see any problems with this solution?
function my_round($number, $decimals)
return floor($number) + round(round($number - floor($number), $decimals + 4), $decimals);
}
The "+ 4" is somewhat arbitrary (about half of the trailing digits of detail), but is attempting to be accurate enough without being so accurate as to run into the .499999999 issue causing this whole thing.
Upvotes: 0
Reputation: 7953
It rounds as expected for me. Have you tried explicitly setting the mode parameter to round()
?
round( 2048.615, 2, PHP_ROUND_HALF_UP); // however, PHP_ROUND_HALF_UP is the default
EDIT: It looks like round()
was changed in PHP 5.3.0:
Changed round() to act more intuitively when rounding to a certain precision and round very large and very small exponents correctly. (Christian Seiler)2
Upvotes: 1
Reputation: 180787
Most likely your particular round
function is performing Banker's Rounding (or PHP_ROUND_HALF_EVEN).
If you want a different kind of rounding, use one of the other PHP rounding variants:
<?php
echo round(9.5, 0, PHP_ROUND_HALF_UP); // 10
echo round(9.5, 0, PHP_ROUND_HALF_DOWN); // 9
echo round(9.5, 0, PHP_ROUND_HALF_EVEN); // 10
echo round(9.5, 0, PHP_ROUND_HALF_ODD); // 9
echo round(8.5, 0, PHP_ROUND_HALF_UP); // 9
echo round(8.5, 0, PHP_ROUND_HALF_DOWN); // 8
echo round(8.5, 0, PHP_ROUND_HALF_EVEN); // 8
echo round(8.5, 0, PHP_ROUND_HALF_ODD); // 9
?>
Upvotes: 1
Reputation: 177550
2048.615 is actually 2048.6149999999998, so it will round down to 2048.61 no matter the rounding method used.
Upvotes: 1