【问题标题】:PHP Rounding NumbersPHP 舍入数字
【发布时间】:2011-01-05 16:21:36
【问题描述】:

我似乎无法弄清楚如何始终在 PHP 中进行四舍五入。 ceil() 将是显而易见的选择,但我需要 round() 提供的第二个参数“precision”相同的功能。这是一个例子:

// 期望的结果:6250 回声轮(6244.64,-2); // 返回 6200 回声轮(6244.64,-1); // 返回 6240 echo ceil(6244.64) // 返回 6245

我需要始终将数字四舍五入,以便我可以根据图表的参数计算等数。

【问题讨论】:

    标签: php rounding


    【解决方案1】:

    来自http://php.net/manual/en/function.ceil.php的评论:

    Quick and dirty `ceil` type function with precision capability.
    
    function ceiling($value, $precision = 0) {
        return ceil($value * pow(10, $precision)) / pow(10, $precision);
    }
    

    【讨论】:

    • 我认为操作顺序是混淆的,你需要在ceil之前先除,然后再乘,而不是反过来,不是吗?
    • @njk: ceiling(6244.64, -1) 给出所需的结果 6250。请注意,在这种情况下精度为负数。
    • 这将返回 true:ceiling(77.4, 2) === 77.41。功能坏了。
    • @bzeaman... 我不认为该功能已损坏。以两位小数精度要求 77.4 的上限就像要求 ceiling( 77.400 , 2 )
    • @user1822391 是的,77.477.400 等相同,但77.4 的上限根本不应该产生77.41
    【解决方案2】:

    其中一些答案存在浮点运算问题,如this answer 所示,可能会失败。对于所有情况下的防弹解决方案,请使用这些:

    /**
     * Used to round up based on the decimal place, for example rounding up to the nearest penny
     * http://stackoverflow.com/questions/8239600/rounding-up-to-the-second-decimal-place
     * @param float $value
     * @param integer $precision
     * @return number
     */
    public 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);
    }
    
    /**
     * Used to round up based on the decimal place, for example rounding up to the nearest penny
     * http://stackoverflow.com/questions/8239600/rounding-up-to-the-second-decimal-place
     * @param float $value
     * @param integer $precision
     * @return number
     */
    public function Floor($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);
    }
    

    【讨论】:

      【解决方案3】:

      由于版本 ceil(pow(10, $precision) * $value) / pow(10, $precision); 在某些情况下会失败,例如如here 所述,round_up(2.22, 2) 给出了不正确的 2.23,因此我已将 string solution for round_down() 调整为我们的 round_up() 问题。这是结果(不包括负精度):

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

      我不知道它是防弹的,但至少它消除了上面提到的失败。我没有进行二进制到十进制的数学分析,但如果 $floorValue + pow(10, 0 - $precision) 有效 总是如预期那样应该没问题。如果您发现一些失败的案例,请告诉我 - 我们应该寻找另一种解决方案 :)

      【讨论】:

      • 使用整数部分和小数部分是个好主意,但您应该使用单个字符。此函数不适用于产生浮点数(77.41000000000001)而不是浮点数(77.41)的上限(77.401, 2)。最佳答案是 Nico Westerdale
      【解决方案4】:

      你可以除以 10,ceil();然后乘以十

      【讨论】:

        【解决方案5】:
        echo 10*ceil($number/10);
        

        【讨论】:

          【解决方案6】:

          另一个精确的 ceil 解决方案,没有 pow,看起来两边都可以工作 9 位:

          $v = 123400100100100101;
          $a1 = 444444444.4;
          $a2 = .04444444444;
          $b1 = 111111111.1;
          $b2 = .01111111111;
          echo $v . "\n";
          for ($i = 0; $i < 18; $i ++) {
              $v = $v/10;
              for ($j = -9; $j < 10; $j++) {
                  echo $i . ':' . $j . ":" . round($v
                      + round($a1, $j + 1) + round($a2, $j + 1)
                      - round($a1, $j) - round($a2, $j)
                      + round($b1, $j + 1) + round($b2, $j + 1)
                      - round($b1, $j) - round ($b2, $j),
                      $j, PHP_ROUND_HALF_DOWN) . "\n";
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2016-12-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-05-13
            • 1970-01-01
            • 1970-01-01
            • 2022-08-12
            相关资源
            最近更新 更多