4

In PHP how would i round up the value 22.04496 so that it becomes 22.05? It seems that round(22.04496,2) = 22.04. Should it not be 22.05??

Thanks in advance

Salman A
  • 262,204
  • 82
  • 430
  • 521
Pjn2020
  • 527
  • 1
  • 8
  • 18
  • It only considers the digit after `4` (which is also `4`) then `22.04` is correct. It is not rounding first 96 to 100 and then 45 to 50. – Felix Kling Jun 21 '11 at 14:21
  • 2
    `Should it not be 22.05??` not really? 044 rounds down to 04, 046 would round up to 05, works as designed – Pekka Jun 21 '11 at 14:21
  • 6
    22.04496 is closer to 22.04 than to 22.05. Look for yourself: `22.04496 - 22.04 = 0.00496` but `22.04496 - 22.05 = -0.00504` – Emil Vikström Jun 21 '11 at 14:22
  • This seems like a question better suited for http://math.stackexchange.com/, IMO – Justin ᚅᚔᚈᚄᚒᚔ Jun 21 '11 at 14:38
  • Basically i need to get the same result as given in js by this function: function roundNumber(num, dec) { var result = Math.round( Math.round( num * Math.pow( 10, dec + 2 ) ) / Math.pow( 10, 2 ) ) / Math.pow(10, dec); return result; } – Pjn2020 Jun 21 '11 at 14:47

6 Answers6

7

you can do it using ceil and multiplying and dividing by a power of 10.

echo ceil( 1.012345 * 1000)/1000;

1.013
Linus Kleen
  • 33,871
  • 11
  • 91
  • 99
Gidon Wise
  • 1,896
  • 1
  • 11
  • 11
  • This is more elegant than my solution which was just to add .05 to the original number and still use the round method i.e. round(#.####+0.05, 2) – Domenic D. Jun 20 '13 at 02:43
  • So, 1.012345 rounds up to 1.013 ? how ? 1.012345 1.01235 1.0124 – Omarrrio Mar 31 '16 at 16:08
  • 7
    This method is flawed: `ceil(77.4 * 100) / 100 === 77.41`. – bzeaman Apr 15 '17 at 09:28
  • The multiplication and dividing number is `pow(10, $dp)` where `$dp` is the number of decimal places you want to round up to. That may be useful to know for rounding to an arbitrary number of decimal places. – Jason Jan 07 '22 at 01:32
3

Do not do multiplication inside a ceil, floor or round function! You'll get floating point errors and it can be extremely unpredictable. To avoid this do:

function ceiling($value, $precision = 0) {
    $offset = 0.5;
    if ($precision !== 0)
        $offset /= pow(10, $precision);
    $final = round($value + $offset, $precision, PHP_ROUND_HALF_DOWN);
    return ($final == -0 ? 0 : $final);
}

For example ceiling(2.2200001, 2) will give 2.23.

Based on comments I've also added my floor function as this has similar problems:

function flooring($value, $precision = 0) {
    $offset = -0.5;
    if ($precision !== 0)
        $offset /= pow(10, $precision);
    $final = round($value + $offset, $precision, PHP_ROUND_HALF_UP);
    return ($final == -0 ? 0 : $final);
}
Nico Westerdale
  • 2,147
  • 1
  • 24
  • 31
2

I think the best way:

echo ceil(round($value * 100)) / 100;

Example:

$value = 77.4;
echo ceil($value * 100) / 100; // 77.41 - WRONG!
echo ceil(round($value * 100)) / 100; // 77.4 - OK!
eep
  • 61
  • 3
2

The round function of PHP can handle an additional argument, which controls how the rounding is done: http://php.net/manual/en/function.round.php

Examples from the link:

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
Linus Kleen
  • 33,871
  • 11
  • 91
  • 99
Daniel
  • 428
  • 3
  • 8
  • Note that this does require PHP 5.3 – Joseph Jun 21 '11 at 14:27
  • 6
    This doesn't make a difference for this case: `php > echo round(22.04496, 2, PHP_ROUND_HALF_DOWN);` `22.04` `php > echo round(22.04496, 2, PHP_ROUND_HALF_UP);` `22.04` – hoppa Jun 21 '11 at 14:27
1

It's not working well.

round(1.211,2,PHP_ROUND_HALF_UP); 
// Res: 1.21

My Solution:

$number = 1.211;

echo myCeil($number,2);

function myCeil($number,$precision = 0){
    $pow = pow(10,$precision);
    $res = (int)($number * $pow) / $pow;
    
    if($number > $res){
        $res += 1 / $pow;
    }
    return $res;
}
// Res 1.22
-3

Why should it be 22.05? The third decimal is less than 5, hence when you round it to 2 decimal precision it's rounded down to 22.04

reko_t
  • 55,302
  • 10
  • 87
  • 77