• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • round()

    (PHP 4, PHP 5, PHP 7)

    对浮点数进行四舍五入

    说明

    round(float $val[,int $precision= 0[,int $mode= PHP_ROUND_HALF_UP]]):float

    返回将$val根据指定精度$precision(十进制小数点后数字的数目)进行四舍五入的结果。$precision也可以是负数或零(默认值)。

    Note:PHP 默认不能正确处理类似"12,300.2"的字符串。见字符串转换为数值。

    参数

    $val

    要处理的值

    $precision

    可选的十进制小数点后数字的数目。

    $mode

    以下之一:PHP_ROUND_HALF_UPPHP_ROUND_HALF_DOWNPHP_ROUND_HALF_EVENPHP_ROUND_HALF_ODD

    返回值

    四舍五入后的值

    范例

    Example #1round()例子

    <?php
    echo round(3.4);         // 3
    echo round(3.5);         // 4
    echo round(3.6);         // 4
    echo round(3.6, 0);      // 4
    echo round(1.95583, 2);  // 1.96
    echo round(1241757, -3); // 1242000
    echo round(5.045, 2);    // 5.05
    echo round(5.055, 2);    // 5.06
    ?>
    

    Example #2$mode例子

    <?php
    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
    echo round(8.5, 0, PHP_ROUND_HALF_UP);   // 9
    echo round(8.5, 0, PHP_ROUND_HALF_DOWN); // 8
    echo round(8.5, 0, PHP_ROUND_HALF_EVEN); // 8
    echo round(8.5, 0, PHP_ROUND_HALF_ODD);  // 9
    ?>
    

    更新日志

    版本说明
    5.3.0引入了$mode参数
    5.2.7round()的内部运作修改符合 C99 的标准。

    参见

    In my opinion this function lacks two flags:
    - PHP_ROUND_UP - Always round up.
    - PHP_ROUND_DOWN - Always round down.
    In accounting, it's often necessary to always round up, or down to a precision of thousandths.
    <?php
    function round_up($number, $precision = 2)
    {
      $fig = (int) str_pad('1', $precision, '0');
      return (ceil($number * $fig) / $fig);
    }
    function round_down($number, $precision = 2)
    {
      $fig = (int) str_pad('1', $precision, '0');
      return (floor($number * $fig) / $fig);
    }
    ?>
    
    If you have negative zero and you need return positive number simple add +0:
    $number = -2.38419e-07;
    var_dump(round($number,1));//float(-0)
    var_dump(round($number,1) + 0);//float(0)
    As PHP doesn't have a a native number truncate function, this is my solution - a function that can be usefull if you need truncate instead round a number.
    <?php
    /**
     * Truncate a float number, example: <code>truncate(-1.49999, 2); // returns -1.49
     * truncate(.49999, 3); // returns 0.499
     * </code>
     * @param float $val Float number to be truncate
     * @param int f Number of precision
     * @return float
     */
    function truncate($val, $f="0")
    {
      if(($p = strpos($val, '.')) !== false) {
        $val = floatval(substr($val, 0, $p + 1 + $f));
      }
      return $val;
    }
    ?>
    Originally posted in http://stackoverflow.com/a/12710283/1596489
    I discovered that under some conditions you can get rounding errors with round when converting the number to a string afterwards.
    To fix this I swapped round() for number_format().
    Unfortunately i cant give an example (because the number cant be represented as a string !)
    essentially I had round(0.688888889,2);
    which would stay as 0.68888889 when printed as a string.
    But using number_format it correctly became 0.69.
    PHP 5.3, 5.4, 5.5
    <?php
    $fInfinty = pow(1000, 1000); // float(INF)
    $fResult = round(123.456, $fInfinty); // double(123)
    ?>
    PHP 5.6
    <?php
    $fInfinty = pow(1000, 1000); // float(INF)
    $fResult = round(123.456, $fInfinty); // float(0)
    ?>
    PHP 7
    <?php
    $fInfinty = pow(1000, 1000); // float(INF)
    $fResult = round(123.456, $fInfinty); // null
    ?>
    
    If you'd only want to round for displaying variables (not for calculating on the rounded result) then you should use printf with the float:
    <?php printf ("%6.2f",3.39532); ?>
    This returns: 3.40 .
    function mround($val, $f=2, $d=6){
      return sprintf("%".$d.".".$f."f", $val);
    }
    echo mround(34.89999); //34.90
    Here is function that rounds to a specified increment, but always up. I had to use it for price adjustment that always went up to $5 increments.
    <?php 
    function roundUpTo($number, $increments) {
      $increments = 1 / $increments;
      return (ceil($number * $increments) / $increments);
    }
    ?>
    
    This function will let you round to an arbitrary non-zero number. Zero of course causes a division by zero.
    <?php
    function roundTo($number, $to){
      return round($number/$to, 0)* $to;
    }
    echo roundTo(87.23, 20); //80
    echo roundTo(-87.23, 20); //-80
    echo roundTo(87.23, .25); //87.25
    echo roundTo(.23, .25); //.25
    ?>
    
    Here's a function to round to an arbitary number of significant digits. Don't confuse it with rounding to a negative precision - that counts back from the decimal point, this function counts forward from the Most Significant Digit.
    ex:
    <?php
    round(1241757, -3); // 1242000
    RoundSigDigs(1241757, 3); // 1240000
    ?>
    Works on negative numbers too. $sigdigs should be >= 0
    <?php
    function RoundSigDigs($number, $sigdigs) {
      $multiplier = 1;
      while ($number < 0.1) {
        $number *= 10;
        $multiplier /= 10;
      }
      while ($number >= 1) {
        $number /= 10;
        $multiplier *= 10;
      }
      return round($number, $sigdigs) * $multiplier;
    }
    ?>
    
    Please note that the format of this functions output also depends on your locale settings. For example, if you have set your locale to some country that uses commas to separate decimal places, the output of this function also uses commas instead of dots.
    This might be a problem when you are feeding the rounded float number into a database, which requires you to separate decimal places with dots.
    See it in action:
    <?php
      echo round('3.5558', 2);
      setlocale(constant('LC_ALL'), 'et_EE.UTF-8');
      echo '<br />'. round('3.5558', 2);
    ?>
    The output will be:
    3.56
    3,56
    this function (as all mathematical operators) takes care of the setlocale setting, resulting in some weirdness when using the result where the english math notation is expected, as the printout of the result in a width: style attribute!
    <?php
    $a=3/4;
    echo round($a, 2); // 0.75
    setlocale(LC_ALL, 'it_IT@euro', 'it_IT', 'it');
    $b=3/4;
    echo round($b,2); // 0,75
    ?>
    
    Excel-like ROUNDUP function:
    public static function round_up($value, $places) 
    {
      $mult = pow(10, abs($places)); 
       return $places < 0 ?
      ceil($value / $mult) * $mult :
        ceil($value * $mult) / $mult;
    }
    echo round_up(12345.23, 1); // 12345.3
    echo round_up(12345.23, 0); // 12346 
    echo round_up(12345.23, -1); // 12350 
    echo round_up(12345.23, -2); // 12400 
    echo round_up(12345.23, -3); // 13000 
    echo round_up(12345.23, -4); // 20000
    Unexpected result or misunderstanding (php v5.5.9)
    <?php
    echo round(1.55, 1, PHP_ROUND_HALF_DOWN); // 1.5
    echo round(1.551, 1, PHP_ROUND_HALF_DOWN); //1.6
    ?>
    
    round() will sometimes return E notation when rounding a float when the amount is small enough - see https://bugs.php.net/bug.php?id=44223 . Apparently it's a feature.
    To work around this "feature" when converting to a string, surround your round statement with an sprintf:
    sprintf("%.10f", round( $amountToBeRounded, 10));
    When you have a deal with money like dollars, you need to display it under this condition:
    -format all number with two digit decimal for cents.
    -divide 1000 by ,
    -round half down for number with more than two decimal
    I approach it using round function inside the number_format function:
    number_format((float)round( 625.371 ,2, PHP_ROUND_HALF_DOWN),2,'.',',') // 625.37
    number_format((float)round( 625.379 ,2, PHP_ROUND_HALF_DOWN),2,'.',',') // 625.38
    number_format((float)round( 1211.20 ,2, PHP_ROUND_HALF_DOWN),2,'.',',') // 1,211.20
    number_format((float)round( 625 ,2, PHP_ROUND_HALF_DOWN),2,'.',',')   // 625.00
    Solving round_down() problem: 
    -----------------------------
    Use of <?php floor(pow(10, $precision) * $value) / pow(10, $precision); ?> fails in some cases, e.g. round_down(2.05, 2) gives incorrect 2.04.
    Here is a "string" solution (https://stackoverflow.com/a/26491492/1245149) of the problem (a negative precision is not covered):
    <?php
    function round_down($value, $precision) {    
      $value = (float)$value;
      $precision = (int)$precision;
      if ($precision < 0) { 
        $precision = 0;
      }
      $decPointPosition = strpos($value, '.');
      if ($decPointPosition === false) { 
        return $value;
      }
      return (float)(substr($value, 0, $decPointPosition + $precision + 1));    
    } 
    ?>
    Solving round_up() problem:
    ---------------------------
    Use of <?php ceil(pow(10, $precision) * $value) / pow(10, $precision);?> fails in some cases, e.g. round_up(2.22, 2) gives incorrect 2.23 (https://stackoverflow.com/a/8239620/1245149).
    Adapting the above round_down() "string" solution I have got this result (a negative precision is not covered):
    <?php
    function round_up($value, $precision) {    
      $value = (float)$value;
      $precision = (int)$precision;
      if ($precision < 0) { 
        $precision = 0;
      }
      $decPointPosition = strpos($value, '.');
      if ($decPointPosition === false) { 
        return $value;
      }
      $floorValue = (float)(substr($value, 0, $decPointPosition + $precision + 1));
      $followingDecimals = (int)substr($value, $decPointPosition + $precision + 1);
      if ($followingDecimals) {
        $ceilValue = $floorValue + pow(10, -$precision); // does this give always right result?
      }
      else {
        $ceilValue = $floorValue;
      }
      return $ceilValue;        
    }
    ?>
    I don't know it is bulletproof, but at least it removes the above mentioned fail. I have done no binary-to-decimal-math-analysis but if `$floorValue + pow(10, 0 - $precision)` works
    always as expected then it should be ok.
    It should just be noted that what is called "precision" on this page is more correctly called accuracy; precision is the total number of significant digits on both sides of the decimal point, while accuracy is the number of digits to the right of the point. It's a common confusion.
    Note that PHP 5.3 didn't just introduce $mode, it rewrote the rounding implementation completely to eliminate many kinds of rounding errors common to rounding floating point values.
    That's why round() gives you the correct result even when floor/ceil don't.
    For example, floor(0.285 * 100 + 0.5) VS round(0.285*100 + 0.5). First one gives 28, second one gives 29.
    More details here: https://wiki.php.net/rfc/rounding
    /**
     * Round to first significant digit
     * +N to +infinity
     * -N to -infinity
     *
     */
    function round1stSignificant ( $N ) {
     if ( $N === 0 ) {
      return 0;
     }
     $x = floor ( log10 ( abs( $N ) ) );
     return ( $N > 0 )
      ? ceil( $N * pow ( 10, $x * -1 ) ) * pow( 10, $x )
      : floor( $N * pow ( 10, $x * -1 ) ) * pow( 10, $x );
    }
    echo round1stSignificant( 39144818 ) . PHP_EOL;
    echo round1stSignificant( 124818 ) . PHP_EOL;
    echo round1stSignificant( 0.07468 ) . PHP_EOL;
    echo round1stSignificant( 0 ) . PHP_EOL;
    echo round1stSignificant( -0.07468 ) . PHP_EOL;
    /**
     * Output
     * 
     * 40000000
     * 200000
     * 0.08
     * 0
     * -0.08
     * 
     */
    This functions return ceil($nb) if the double or float value is bigger than "$nb.5" else it's return floor($nb)
    <?php
      function arounds_int($nb) {
       
        if(!is_numeric($nb)) {
          return false;
        }
        
        $sup = round($nb);
        $inf = floor($nb);
        $try = (double) $inf . '.5' ; 
        
        if($nb > $try) {
          return $sup;
        }
        
        return $inf;
      }
    ?>
    
    Here is a short neat function to round minutes (hour) ...
    <?php
    function minutes_round ($hour = '14:03:32', $minutes = '5', $format = "H:i")
    {
      // by Femi Hasani [www.vision.to]
      $seconds = strtotime($hour);
      $rounded = round($seconds / ($minutes * 60)) * ($minutes * 60);
      return date($format, $rounded);
    }
    ?>
    You decide to round to nearest minute ...
    example will produce : 14:05
    In case someone will need a "graceful" rounding (that changes it's precision to get a non 0 value) here's a simple function:
    function gracefulRound($val, $min = 2, $max = 4) {
      $result = round($val, $min);
      if ($result == 0 && $min < $max) {
        return gracefulRound($val, ++$min, $max);
      } else {
        return $result;
      }
    }
    Usage:
    $_ = array(0.5, 0.023, 0.008, 0.0007, 0.000079, 0.0000048);
    foreach ($_ as $val) {
      echo "{$val}: ".gracefulRound($val)."\n";
    }
    Output:
    0.5: 0.5
    0.023: 0.02
    0.008: 0.01
    0.0007: 0.001
    0.000079: 0.0001
    0.0000048: 0
    To round any number to a given number of significant digits, use log10 to find out its magnitude:
    <?php round($n, ceil(0 - log10($n)) + $sigdigits); ?>
    Or when you have to display a per-unit price which may work out to be less than a few cents/pence/yen you can use:
    <?php
    // $exp = currency decimal places - 0 for Yen/Won, 2 for most others
    $dp = ceil(0 - log10($n)) + $sigdigits;
    $display = number_format($amount, ($exp>$dp)?$exp:$dp);
    ?>
    This always displays at least the number of decimal places required by the currency, but more if displaying the unit price with precision requires it - eg: 'English proofreading from $0.0068 per word', 'English beer from $6.80 per pint'.
    This function has strange. behaviors:
    <?php
    echo round(0.045, 2);   // 0.05
    echo round(0.45, 1);   // 0.5
    echo round(1.045-1, 2);  // 0.04 !!!
    echo round(1.45-1, 1);   // 0.5
    Because this function is missing round up and round down constants and the top note doesn't really show you how to round up or down to the nearest number, here is an easy way to always round up or always round down to the nearest number.
    int is the number you want to round
    n is the nearest number you want rounded to.
    Round up to the nearest number
    function round_up($int, $n) {
      return ceil($int / $n) * $n;
    }
    And to round down to the nearest number
    function round_down(int, $n) {
      return floor($int / $n) * $n;
    }
    Beware strange behaviour if number is negative and precision is bigger than the actual number of digits after comma.
    round(-0.07, 4);
    returns
    -0.07000000000000001
    So if you validate it against a regular expression requiring the maximum amount of digits after comma, you'll get into trouble.
    the result of this function always depends on the underlying C function. There have been a lot of compiler bugs and floating-point precission problems involving this function. Right now the following code:
    <?php
    echo round(141.075, 2);
    ?>
    returns:
    141.07
    on my machine.
    So never really trust this function when you do critical calculations like accounting stuff!
    Instead: use only integers or use string comparisons.
    Since the mode parameter for options like PHP_ROUND_HALF_UP is available as of PHP 5.3, here is an alternative for ceiling:
    <?php echo 252 / 40; // 6.3 ?>
    If I round this:
    <?php echo round(252 / 40); // 6 ?>
    You can also use a ceil (which might be useful for pagination):
    <?php echo ceil(252/40); // 7 ?>
    [Edited by: googleguy@php.net for clarity]
    Formats a number to the specified number of significant figures.
    <?php
    /**
     * Formats numbers to the specified number of significant figures.
     *
     * @author Bevan Rudge, Drupal.geek.nz
     *
     * @param number $number
     *  The number to format.
     * @param integer $sf
     *  The number of significant figures to round and format the number to.
     * @return string
     *  The rounded and formatted number.
     */
    function format_number_significant_figures($number, $sf) {
     // How many decimal places do we round and format to?
     // @note May be negative.
     $dp = floor($sf - log10(abs($number)));
     // Round as a regular number.
     $number = round($number, $dp);
     // Leave the formatting to format_number(), but always format 0 to 0dp.
     return number_format($number, 0 == $number ? 0 : $dp);
    }
    ?>
    
    $a = .9;
      $b = .8;
      $d = .1;
      $e = .2;
      $x = $a-$b;
      $y = $e-$d;
      $f = round($x,2);
      echo $f;
      if($f==$y){
        echo "ok";
      }

    上篇:rand()

    下篇:sin()