2009-10-12 144 views
2

我有以下功能回合数为$最近数字结尾最接近的数字,我想知道是否有做同样的一个更优雅的方式四舍五入到最接近的结局位数

/** 
* 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 2009-10-12 16:21:57

回答

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'作为我的问题中提供的示例。 – 2010-01-07 22:11:24

+0

您是否更改'$ type'参数? 'roundToDigits(94,9''floor')== 89','roundToDigits(94,9''ceil')== 99','roundToDigits(94,9''round')== 99' – nickf 2010-01-07 22:55:34

+0

Ooops ,不,我没有! :O整洁的解决方案,我只是改变'$ pow = pow(10,floor(log($ suffix,10)+ 1));'来处理小数。谢谢! – 2012-04-11 22:12:03

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; 
} 

编辑:添加了什么我认为你从负输入想要

+0

有太多的重复,它是优雅的。 – slikts 2009-10-12 19:10:11

+0

@Reinis I:好的,我把它变成了一个小玩意儿。 – Kip 2009-10-12 21:21:56