PHP 四舍五入数字

发布于 2024-08-18 13:03:31 字数 280 浏览 4 评论 0原文

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

// Desired result: 6250
echo round(6244.64, -2); // returns 6200
echo round(6244.64, -1); // returns 6240
echo ceil(6244.64) // returns 6245

我需要数字始终向上舍入,以便我可以根据图表的参数计算等除数。

I cannot seem to figure out how to always round up in PHP. ceil() would be the obvious choice but I need the same functionality that round() provides with its second parameter "precision". Here is an example:

// Desired result: 6250
echo round(6244.64, -2); // returns 6200
echo round(6244.64, -1); // returns 6240
echo ceil(6244.64) // returns 6245

I need the number to always round up so that I can calculate an equal divisor based on parameters for a chart.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

↙厌世 2024-08-25 13:03:31

来自对 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);
}

From a comment on 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);
}
天暗了我发光 2024-08-25 13:03:31

其中一些答案存在浮点运算问题,可能会失败,如

/**
 * 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);
}

Some of these answers have issues with floating point arithmetic which can fail as shown in this answer. For a bulletproof solution in all cases, use these:

/**
 * 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);
}
[浮城] 2024-08-25 13:03:31

由于版本 ceil(pow(10, $ precision) * $value) / pow(10, $ precision); 在某些情况下失败,例如 round_up(2.22, 2) 给出了错误的 2.23,如前面提到的 这里,所以我改编了这个< em>string 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) 有效
总是如预期的那样应该没问题。如果您发现一些失败的案例,请告诉我 - 我们应该寻找另一个解决方案:)

As version ceil(pow(10, $precision) * $value) / pow(10, $precision); fails in some cases, e.g. round_up(2.22, 2) gives incorrect 2.23 as mentioned here, so I have adapted this string solution for round_down() to our round_up() problem. This is the result (a negative precision is not covered):

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. If you will find some failing case let me know - we should look for another solution :)

花桑 2024-08-25 13:03:31

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

You could divide by 10, ceil(); and then multiply by ten

被翻牌 2024-08-25 13:03:31
echo 10*ceil($number/10);
echo 10*ceil($number/10);
十年九夏 2024-08-25 13:03:31

另一种精确的 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";
    }
}

One more solution for ceil with precision, no pow, it looks like works 9 digits both sides:

$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";
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文