Asked  7 Months ago    Answers:  5   Viewed   37 times

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?

 Answers

82

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
Wednesday, March 31, 2021
 
BrunoRamalho
answered 7 Months ago
19

use this function

function rndfunc($x){
  return round($x * 2, 1) / 2;
}
Wednesday, March 31, 2021
 
tedders
answered 7 Months ago
74

After a night lost trying to solve this problem I believe I've found a rather simple solution, here it is:

function bcceil($number)
{
    if (strpos($number, '.') !== false) {
        if (preg_match("~.[0]+$~", $number)) return bcround($number, 0);
        if ($number[0] != '-') return bcadd($number, 1, 0);
        return bcsub($number, 0, 0);
    }
    return $number;
}

function bcfloor($number)
{
    if (strpos($number, '.') !== false) {
        if (preg_match("~.[0]+$~", $number)) return bcround($number, 0);
        if ($number[0] != '-') return bcadd($number, 0, 0);
        return bcsub($number, 1, 0);
    }
    return $number;
}

function bcround($number, $precision = 0)
{
    if (strpos($number, '.') !== false) {
        if ($number[0] != '-') return bcadd($number, '0.' . str_repeat('0', $precision) . '5', $precision);
        return bcsub($number, '0.' . str_repeat('0', $precision) . '5', $precision);
    }
    return $number;
}

I think I didn't miss anything, if someone can spot any bug please let me know. Here are some tests:

assert(bcceil('4') == ceil('4')); // true
assert(bcceil('4.3') == ceil('4.3')); // true
assert(bcceil('9.999') == ceil('9.999')); // true
assert(bcceil('-3.14') == ceil('-3.14')); // true

assert(bcfloor('4') == floor('4')); // true
assert(bcfloor('4.3') == floor('4.3')); // true
assert(bcfloor('9.999') == floor('9.999')); // true
assert(bcfloor('-3.14') == floor('-3.14')); // true

assert(bcround('3', 0) == number_format('3', 0)); // true
assert(bcround('3.4', 0) == number_format('3.4', 0)); // true
assert(bcround('3.5', 0) == number_format('3.5', 0)); // true
assert(bcround('3.6', 0) == number_format('3.6', 0)); // true
assert(bcround('1.95583', 2) == number_format('1.95583', 2)); // true
assert(bcround('5.045', 2) == number_format('5.045', 2)); // true
assert(bcround('5.055', 2) == number_format('5.055', 2)); // true
assert(bcround('9.999', 2) == number_format('9.999', 2)); // true
Thursday, June 10, 2021
 
Powering
answered 5 Months ago
28

I would just create a couple methods;

int RoundUp(int toRound)
{
     if (toRound % 10 == 0) return toRound;
     return (10 - toRound % 10) + toRound;
}

int RoundDown(int toRound)
{
    return toRound - toRound % 10;
}

Modulus gives us the remainder, in the case of rounding up 10 - r takes you to the nearest tenth, to round down you just subtract r. Pretty straight forward.

Sunday, June 13, 2021
 
Savageman
answered 5 Months ago
97

PHP supports negative precision for its round function:

$a = round($a, -1);

it's pretty much the same as writing:

$a = round($a/10)*10;
Tuesday, August 24, 2021
 
fillobotto
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :