2009-10-12 3 views
2

У меня есть следующая функция, которая округляет число до ближайшего числа, заканчивающихся цифры $ ближайшего, и мне было интересно, если есть более элегантный способ делать то же самое.округление до ближайшего целого Ending Digits

/** 
* Rounds the number to the nearest digit(s). 
* 
* @param int $number 
* @param int $nearest 
* @return int 
*/ 

function roundNearest($number, $nearest, $type = null) 
{ 
    $result = abs(intval($number)); 
    $nearest = abs(intval($nearest)); 

    if ($result <= $nearest) 
    { 
     $result = $nearest; 
    } 

    else 
    { 
     $ceil = $nearest - substr($result, strlen($result) - strlen($nearest)); 
     $floor = $nearest - substr($result, strlen($result) - strlen($nearest)) - pow(10, strlen($nearest)); 

     switch ($type) 
     { 
      case 'ceil': 
       $result += $ceil; 
      break; 

      case 'floor': 
       $result += $floor; 
      break; 

      default: 
       $result += (abs($ceil) <= abs($floor)) ? $ceil : $floor; 
      break; 
     } 
    } 

    if ($number < 0) 
    { 
     $result *= -1; 
    } 

    return $result; 
} 

Некоторые примеры:

roundNearest(86, 9); // 89 
roundNearest(97, 9); // 99 
roundNearest(97, 9, 'floor'); // 89 

Заранее спасибо!

PS: Этот вопрос не о округление до ближайшего кратного .

+0

почему вы изобретать колесо? – markus

ответ

5

Это работает для меня:

function roundToDigits($num, $suffix, $type = 'round') { 
    $pow = pow(10, floor(log($suffix, 10) + 1)); 
    return $type(($num - $suffix)/$pow) * $pow + $suffix; 
}; 

$type должен быть либо «перекрывать», «пол», или «круглый»

+0

Всегда округляет номера, возвращает '79',' 89' и '89' для примеров, приведенных в моем вопросе. –

+0

Вы изменили параметр '$ type'? 'roundToDigits (94,9, 'floor') == 89',' roundToDigits (94,9, 'ceil') == 99', 'roundToDigits (94,9, 'round') == 99' – nickf

+0

Ooops , нет, я этого не делал! : O Neat solution, я бы просто изменил '$ pow = pow (10, floor (log ($ suffix, 10) + 1));' также обрабатывать десятичные числа. Благодаря! –

2

Я думаю, что это должно работать, и это более элегантно ко мне, по крайней мере:

function roundNearest($number, $nearest, $type = null) 
{ 
    if($number < 0) 
    return -roundNearest(-$number, $nearest, $type); 

    $nearest = abs($nearest); 
    if($number < $nearest) 
    return $nearest; 

    $len = strlen($nearest); 
    $pow = pow(10, $len); 
    $diff = $pow - $nearest; 

    if($type == 'ciel') 
    $adj = 0.5; 
    else if($type == 'floor') 
    $adj = -0.5; 
    else 
    $adj = 0; 

    return round(($number + $diff)/$pow + $adj)*$pow - $diff; 
} 

Edit: Добавлено что я думаю вы хотите от отрицательных входов.

+0

Слишком много повторений, чтобы он был изящным. – slikts

+0

@Reinis I: OK Я сделал это немного eleganter. – Kip

Смежные вопросы