46

So, I need to create the following functions but my head can't think of any possibility in PHP without complicated math.

  • Round always up to the nearest decimal (1.81 = 1.90, 1.89 = 1.90, 1.85 = 1.90)
  • Round always down to the nearest decimal (1.81 = 1.80, 1.89 = 1.80, 1.85 = 1.80)
  • Round always up to the nearest x.25 / x.50 / x.75 / x.00 (1.81 = 2, 1.32 = 1.50)
  • Round always down to the nearest x.25 / x.50 / x.75 / x.00 (1.81 = 1.75, 1.32 = 1.25)
  • Round always up to the nearest x.50 / 1 (1.23 = 1.50, 1.83 = 2)
  • Round always down to the nearest x.50 / 1 (1.23 = 1, 1.83 = 1.50)

I have searched on Google for 2 hours now and the only things that came up were Excel forums. Is it possible with some simple lines of PHP?

Wiseguy
  • 20,522
  • 8
  • 65
  • 81

4 Answers4

132

Since you're looking for fourths (.00, .25, .50, .75), multiply your number by 4, round to nearest whole number as desired (floor if down, ceil if up), then divide by 4.

1.32, down to nearest fourth:

1.32 * 4 = 5.28
floor(5.28) = 5.00
5.00 / 4 = 1.25

Same principle applies for any other fractions, such as thirds or eighths (.0, .125, .25, .375, .5, .625, .75, .875). For example:

1.77, up to nearest eighth:

1.77 * 8 = 14.16
ceil(14.16) = 15.00
15.00 / 8 = 1.875


Just for fun, you could write a function like this:

function floorToFraction($number, $denominator = 1)
{
    $x = $number * $denominator;
    $x = floor($x);
    $x = $x / $denominator;
    return $x;
}

echo floorToFraction(1.82);      // 1
echo floorToFraction(1.82, 2);   // 1.5
echo floorToFraction(1.82, 3);   // 1.6666666666667
echo floorToFraction(1.82, 4);   // 1.75
echo floorToFraction(1.82, 9);   // 1.7777777777778
echo floorToFraction(1.82, 25);  // 1.8
Wiseguy
  • 20,522
  • 8
  • 65
  • 81
  • You guys are my heroes. Thanks. (And I don't know which one I have to except now as the answer). –  Feb 15 '13 at 21:23
  • I'd go with the answer that actually contains the solution code, rather than just a link elsewhere. Or you could accept the one that was posted first. – Barmar Feb 15 '13 at 21:38
  • I wish i could give you hundreds of upvotes for this! – Horst Feb 13 '14 at 19:49
  • 1
    For anybody looking into this now: just use PHP's [round function](http://php.net/manual/en/function.round.php) – James Spence Mar 17 '15 at 21:31
  • 1
    @James using `round()` alone does not provide the solution to the OPs question – aequalsb Oct 10 '18 at 02:20
5

Please note that the answer isn't really water tight. Since we're dealing with floats here it's not guaranteed that when you divide the rounded number by the denominator it returns a neatly round number. It may return 1.499999999999 instead of 1.5. It's the nature of floating point numbers.

Another round is needed before returning the number from the function.

Just in case someone lands here from google like I did :)

Bart Guliker
  • 57
  • 1
  • 5
  • 1
    Mind adding an example? – Simon Dec 01 '16 at 08:08
  • 4
    @Simon `round(round(2.24 * 4) / 4, 2)`: The inner round function makes it snap to the closest integer. The division can lead to strange floats, so the outer round function rounds it to 2 decimal places. – okdewit Jun 14 '17 at 08:45
  • 1
    @Fx32 your little snippet works great -- maybe you should mention to change the places as needed (for example: `round(round(2.24 * 8) / 8, 3)` to get proper results such as .125, .875 to convert to nearest 1/8 fractional inches. – aequalsb Oct 10 '18 at 02:23
4

According to the mround() function in Excel:

function MRound($num,$parts) {
    $res = $num * $parts;
    $res = round($res);
    return $res /$parts;
}
echo MRound(-1.38,4);//gives -1.5
echo MRound(-1.37,4);//gives -1.25
echo MRound(1.38,4);//gives 1.5
echo MRound(1.37,4);//gives 1.25
Aryeh Beitz
  • 1,974
  • 1
  • 22
  • 23
2

Look at example #3 on here and it is half of your solution - http://php.net/manual/en/function.round.php

Catfish
  • 18,876
  • 54
  • 209
  • 353
  • You guys are my heroes. Thanks. (And I don't know which one I have to except now as the answer). –  Feb 15 '13 at 21:23