Reputation: 813
I want a php function which returns 55 when calling it with 52.
I've tried the round()
function:
echo round(94, -1); // 90
It returns 90 but I want 95.
Thanks.
Upvotes: 81
Views: 80591
Reputation: 31508
round()
(or ceil()
if you want to round up always)The value 5 (the resolution / granularity) can be anything — replaced it in both step 1 and 3
So in summary:
$rounded_number = ceil( $initial_number / 5 ) * 5
Upvotes: 144
Reputation: 518
Probably you can also consider this one liner. It's faster! Works for $num >= 0
and $factor > 0
.
$num = 52;
$factor = 55;
$roundedNum = $num + $factor - 1 - ($num + $factor - 1) % $factor;
Upvotes: 0
Reputation: 508
From Gears library
MathType::roundStep(50, 5); // 50
MathType::roundStep(52, 5); // 50
MathType::roundStep(53, 5); // 55
MathType::floorStep(50, 5); // 50
MathType::floorStep(52, 5); // 50
MathType::floorStep(53, 5); // 50
MathType::ceilStep(50, 5); // 50
MathType::ceilStep(52, 5); // 55
MathType::ceilStep(53, 5); // 55
Source:
public static function roundStep($value, int $step = 1)
{
return round($value / $step) * $step;
}
public static function floorStep($value, int $step = 1)
{
return floor($value / $step) * $step;
}
public static function ceilStep($value, int $step = 1)
{
return ceil($value / $step) * $step;
}
Upvotes: 3
Reputation: 171
I do it like this:
private function roundUpToAny(int $n, $x = 9)
{
return (floor($n / 10) * 10) + $x;
}
Tests:
assert($this->roundUpToAny(0, 9) == 9);
assert($this->roundUpToAny(1, 9) == 9);
assert($this->roundUpToAny(2, 9) == 9);
assert($this->roundUpToAny(3, 9) == 9);
assert($this->roundUpToAny(4, 9) == 9);
assert($this->roundUpToAny(5, 9) == 9);
assert($this->roundUpToAny(6, 9) == 9);
assert($this->roundUpToAny(7, 9) == 9);
assert($this->roundUpToAny(8, 9) == 9);
assert($this->roundUpToAny(9, 9) == 9);
assert($this->roundUpToAny(10, 9) == 19);
assert($this->roundUpToAny(11, 9) == 19);
assert($this->roundUpToAny(12, 9) == 19);
assert($this->roundUpToAny(13, 9) == 19);
assert($this->roundUpToAny(14, 9) == 19);
assert($this->roundUpToAny(15, 9) == 19);
assert($this->roundUpToAny(16, 9) == 19);
assert($this->roundUpToAny(17, 9) == 19);
assert($this->roundUpToAny(18, 9) == 19);
assert($this->roundUpToAny(19, 9) == 19);
Upvotes: 1
Reputation: 31130
I just wrote this function in 20 min, based on many results I found here and there, I don't know why it works or how it works!! :D
I was mainly interested in converting currency numbers from this 151431.1 LBP to 150000.0 LBP. (151431.1 LBP == ~100 USD) which works perfectly so far, however I tried to make it somehow compatible with other currencies and numbers, but not sure if it works fine!!
/**
* Example:
* Input = 151431.1 >> return = 150000.0
* Input = 17204.13 >> return = 17000.0
* Input = 2358.533 >> return = 2350.0
* Input = 129.2421 >> return = 125.0
* Input = 12.16434 >> return = 10.0
*
* @param $value
* @param int $modBase
*
* @return float
*/
private function currenciesBeautifier($value, int $modBase = 5)
{
// round the value to the nearest
$roundedValue = round($value);
// count the number of digits before the dot
$count = strlen((int)str_replace('.', '', $roundedValue));
// remove 3 to get how many zeros to add the mod base
$numberOfZeros = $count - 3;
// add the zeros to the mod base
$mod = str_pad($modBase, $numberOfZeros + 1, '0', STR_PAD_RIGHT);
// do the magic
return $roundedValue - ($roundedValue % $mod);
}
Feel free to modify it and fix it if there's anything wrong
Upvotes: 0
Reputation: 4364
Here is my version of Musthafa's function. This one is more complex but it has support for Float numbers as well as Integers. The number to be rounded can also be in a string.
/**
* @desc This function will round up a number to the nearest rounding number specified.
* @param $n (Integer || Float) Required -> The original number. Ex. $n = 5.7;
* @param $x (Integer) Optional -> The nearest number to round up to. The default value is 5. Ex. $x = 3;
* @return (Integer) The original number rounded up to the nearest rounding number.
*/
function rounduptoany ($n, $x = 5) {
//If the original number is an integer and is a multiple of
//the "nearest rounding number", return it without change.
if ((intval($n) == $n) && (!is_float(intval($n) / $x))) {
return intval($n);
}
//If the original number is a float or if this integer is
//not a multiple of the "nearest rounding number", do the
//rounding up.
else {
return round(($n + $x / 2) / $x) * $x;
}
}
I tried the functions from Knight, Musthafa and even the suggestion from Praesagus. They don't have support for Float numbers and the solutions from Musthafa's & Praesagus do not work correctly in some numbers. Try the following test numbers and do the comparison yourself:
$x= 5;
$n= 200; // D = 200 K = 200 M = 200 P = 205
$n= 205; // D = 205 K = 205 M = 205 P = 210
$n= 200.50; // D = 205 K = 200 M = 200.5 P = 205.5
$n= '210.50'; // D = 215 K = 210 M = 210.5 P = 215.5
$n= 201; // D = 205 K = 205 M = 200 P = 205
$n= 202; // D = 205 K = 205 M = 200 P = 205
$n= 203; // D = 205 K = 205 M = 205 P = 205
** D = DrupalFever K = Knight M = Musthafa P = Praesagus
Upvotes: 1
Reputation: 19225
Round down:
$x = floor($x/5) * 5;
Round up:
$x = ceil($x/5) * 5;
Round to closest (up or down):
$x = round($x/5) * 5;
Upvotes: 90
Reputation: 71150
This can be accomplished in a number of ways, depending on your preferred rounding convention:
Behaviour: 50 outputs 55, 52 outputs 55
function roundUpToAny($n,$x=5) {
return round(($n+$x/2)/$x)*$x;
}
Behaviour: 50 outputs 50, 52 outputs 55, 50.25 outputs 50
function roundUpToAny($n,$x=5) {
return (round($n)%$x === 0) ? round($n) : round(($n+$x/2)/$x)*$x;
}
Behaviour: 50 outputs 50, 52 outputs 55, 50.25 outputs 55
function roundUpToAny($n,$x=5) {
return (ceil($n)%$x === 0) ? ceil($n) : round(($n+$x/2)/$x)*$x;
}
Upvotes: 182
Reputation: 71
function round_up($n, $x = 5) {
$rem = $n % $x;
if ($rem < 3)
return $n - $rem;
else
return $n - $rem + $x;
}
Upvotes: 0
Reputation: 16585
echo $value - ($value % 5);
I know it's an old question, but IMHO using modulus operator is the best way, and far more elegant than the accepted answer.
Upvotes: 4
Reputation: 31
Try this little function I wrote.
function ceilFive($number) {
$div = floor($number / 5);
$mod = $number % 5;
If ($mod > 0) $add = 5;
Else $add = 0;
return $div * 5 + $add;
}
echo ceilFive(52);
Upvotes: 3