# Extension of PHP round() for PHP_ROUND_UP and PHP_ROUND_DOWN

While looking at PHP.net this afternoon, I saw a comment in round() for two functions for rounding UP and DOWN (as opposed to just HALF_UP and DOWN). I liked the suggestion, but wanted a solution that was one function instead of 3, so I came up with the following:

define('PHP_ROUND_UP',   11);
define('PHP_ROUND_DOWN', 12);

function fround($number,$precision = 0, $mode = PHP_ROUND_HALF_UP) { if(is_string($number)) {
$number = preg_replace('/,/','',$number);
}
if (is_numeric($number) && !empty($number)) {
switch($mode) { case PHP_ROUND_UP: case PHP_ROUND_DOWN:$invert = (bool) ($number < 0); if($invert) {
$number *= -1; } if (!empty($precision)) {
$precision = pow(10, (int)$precision);
$number *=$precision;
}
if ($mode == PHP_ROUND_UP) {$number = ceil($number); } else {$number = floor($number); } if (!empty($precision) && !empty($number)) {$number /= $precision; } if($invert) {
$number *= -1; } break; default:$number = round($number,$precision, $mode); break; } } return (float)$number;
}


My questions are about overhead/performance, and really anything else you may have to say. For options other than PHP_ROUND_UP or PHP_ROUND_DOWN it adds minimal overhead, save for stripping commas if the input number is a string (I realize this is additional to what PHP's round() does), so I guess I am asking about the internal logic for PHP_ROUND_UP and PHP_ROUND_DOWN.

The comment that sparked this for me is here.

REVISION

• Mike, if you have taken advice from the answer given to change your code, then you should post a new question with your new code. We have a policy about changing the code or the question after reviews have been given. What you may and may not do after receiving answers – Malachi Dec 30 '15 at 19:22
• 10-4, I just did a quick browse on Meta to double-check, as posting a new CR for every revision seems like it would add a considerable amount of data to SO, but, indeed, it seems that all Meta questions on the topic are all about un-reviewed code, and the handful about reviewed code are just that: "Post again." My bad. – Mike Dec 30 '15 at 19:27
• Side-Note: It would be nice if there was a "Post Revision" button, that created a link to the new revision, would help tying them all together, direct the crowd/conversation, etc. It would also make the requirement clearer. Maybe I will mention this on Meta. – Mike Dec 30 '15 at 19:29

General

Instead of having your function convert string values to numbers, throw an error if, for example !is_float($number). round() only accepts a float value, so I think you should follow their convention. Also, this will allow you to remove is_numeric() (or, above, you could check for is_numeric() only). This if-condition doesn't have an else, so when poor input is entered, the user could potentially not get any response at all -- terrible for debugging! Performance empty($number) is checked two times, you can reduce that to none since is_float() will automatically return false if there is nothing (or throw an error is there's no argument).

• Yes, the preg_replace deviates from round()'s convention, and probably should not be included, but I put it in my function because it deals with some numbers from a DB, I may modify to filter outside the function first. I think is_numeric() is appropriate, as round() accepts any numeric value. As for getting "nothing," the function will return an empty (float), which follows convention 0 === round('hello'); As for $invert, this is nessesary to mimic round() behaviour with negative numbers -124 === round(-123.5) && 124 === round(123.5). I will clean up. – Mike Dec 30 '15 at 19:01 • @Mike On second glance, is_numeric() is comparable to what's in round(), so that's fine. And $invert seems appropriate, I hadn't used round() in a while and had to go test it out! – Alex L Dec 30 '15 at 19:08
• Updated, the use of xor is much more performant, and I LOVE getting a chance to use it when I can. – Mike Dec 30 '15 at 19:13
• Haha very clever, if I think of anything else I'll edit my answer! – Alex L Dec 30 '15 at 19:15