PHP 5.2.17 的 round() 模式 ROUND_HALF_DOWN

发布于 2024-11-29 22:57:01 字数 472 浏览 3 评论 0原文

我需要在 PHP 5.2.17 中模拟 ROUND_HALF_DOWN 模式 - 我无法升级服务器的 PHP 版本。有什么想法如何实现这一目标?

基本思想是 1.895 变成 1.89,而不是像通常使用 round() 那样变成 1.90。

编辑: 这个函数似乎可以解决问题:

function nav_round($v, $prec = 2) {
    // Seems to fix a bug with the ceil function
    $v = explode('.',$v);
    $v = implode('.',$v);
    // The actual calculation
    $v = $v * pow(10,$prec) - 0.5;
    $a = ceil($v) * pow(10,-$prec);
    return number_format( $a, 2, '.', '' );
}

I need to simulate ROUND_HALF_DOWN mode in PHP 5.2.17 - I cannot upgrade the server's PHP version. Any ideas how to achieve this?

The basic idea is that 1.895 becomes 1.89, not 1.90 like it usually does with round().

EDIT:
This function seems to do the trick:

function nav_round($v, $prec = 2) {
    // Seems to fix a bug with the ceil function
    $v = explode('.',$v);
    $v = implode('.',$v);
    // The actual calculation
    $v = $v * pow(10,$prec) - 0.5;
    $a = ceil($v) * pow(10,-$prec);
    return number_format( $a, 2, '.', '' );
}

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

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

发布评论

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

评论(4

安穩 2024-12-06 22:57:01

您可以通过简单地转换为字符串并返回来进行作弊:

$num = 1.895;

$num = (string) $num;

if (substr($num, -1) == 5) $num = substr($num, 0, -1) . '4';

$num = round(floatval($num), 2);

编辑:

这里以函数形式提供它:

echo round_half_down(25.2568425, 6); // 25.256842

function round_half_down($num, $precision = 0)
{
    $num = (string) $num;
    $num = explode('.', $num);
    $num[1] = substr($num[1], 0, $precision + 1);
    $num = implode('.', $num);

    if (substr($num, -1) == 5)
        $num = substr($num, 0, -1) . '4';

    return round(floatval($num), $precision);
}

You can cheat by simply converting to a string and back:

$num = 1.895;

$num = (string) $num;

if (substr($num, -1) == 5) $num = substr($num, 0, -1) . '4';

$num = round(floatval($num), 2);

EDIT:

Here you have it in function form:

echo round_half_down(25.2568425, 6); // 25.256842

function round_half_down($num, $precision = 0)
{
    $num = (string) $num;
    $num = explode('.', $num);
    $num[1] = substr($num[1], 0, $precision + 1);
    $num = implode('.', $num);

    if (substr($num, -1) == 5)
        $num = substr($num, 0, -1) . '4';

    return round(floatval($num), $precision);
}
多彩岁月 2024-12-06 22:57:01

在 PHP 5.3 之前,最简单的方法似乎是从所需精度的最后一个数字后面的数字中减去 1。因此,如果精度为 2 并且希望 1.995 变为 1.99,只需从数字和舍入中减去 0.001。这将始终返回正确的舍入,除了半值将向下舍入而不是向上舍入。

示例 1:

$num = 1.835;
$num = $num - .001; // new number is 1.834
$num = round($num,2);
echo $num;

四舍五入后的值现在为 1.83

对于另一个精度,您只需调整减去 1 的位置即可。

示例 2:

$num = 3.4895;
$num = $num - .0001; // new number is 3.4894
$num = round($num, 3);
echo $num;

四舍五入后的值现在是 3.489

如果您想要一个函数来处理这项工作,请使用以下函数。

function round_half_down($num,$precision)
{ 
    $offset = '0.';
    for($i=0; $i < $precision; $i++)
    {
        $offset = $offset.'0';
    }

    $offset =  floatval($offset.'1');
    $num = $num - $offset;
    $num = round($num, $precision);

    return $num;
}

It seems the easiest method for this prior to PHP 5.3 is to subtract 1 from the number following the last number in the required precision. So if you have precision 2 and want 1.995 to become 1.99 just subtract .001 from the number and round. This will always return a correct round except that the half value will round down rather than up.

Example1:

$num = 1.835;
$num = $num - .001; // new number is 1.834
$num = round($num,2);
echo $num;

The value after rounding is now 1.83

For another precision you just adjust where you subtract the 1 from.

Example2:

$num = 3.4895;
$num = $num - .0001; // new number is 3.4894
$num = round($num, 3);
echo $num;

The value after rounding is now 3.489

If you want a function to handle the work the following function does that.

function round_half_down($num,$precision)
{ 
    $offset = '0.';
    for($i=0; $i < $precision; $i++)
    {
        $offset = $offset.'0';
    }

    $offset =  floatval($offset.'1');
    $num = $num - $offset;
    $num = round($num, $precision);

    return $num;
}
只为一人 2024-12-06 22:57:01

您可以去掉 0.5^p,其中 p 是精度,然后使用上限:

<?php

function round_half_down($v, $prec) {
  $v = $v * pow(10,$prec) - 0.5;
  return ceil($v) * pow(10,-$prec);
}


print round_half_down(9.5,0) . "\n";
print round_half_down(9.05,0) . "\n";
print round_half_down(9.051,0) . "\n";
print round_half_down(9.05,1) . "\n";
print round_half_down(9.051,1) . "\n";
print round_half_down(9.055,2) . "\n";
print round_half_down(1.896,2) . "\n";

?>

产量:

$ php test.php 
9
9
9
9
9.1
9.05
1.9

您会注意到,对于任何数字 x <= p <= x.5,我们得到上限(p - 0.5) = x,对于所有 x+1 => p> x.5,我们得到上限(p - 0.5) = x+1。这应该正是您想要的。

You can take off 0.5^p where p is the precision and then use ceiling:

<?php

function round_half_down($v, $prec) {
  $v = $v * pow(10,$prec) - 0.5;
  return ceil($v) * pow(10,-$prec);
}


print round_half_down(9.5,0) . "\n";
print round_half_down(9.05,0) . "\n";
print round_half_down(9.051,0) . "\n";
print round_half_down(9.05,1) . "\n";
print round_half_down(9.051,1) . "\n";
print round_half_down(9.055,2) . "\n";
print round_half_down(1.896,2) . "\n";

?>

yields:

$ php test.php 
9
9
9
9
9.1
9.05
1.9

You'll note that for any number x <= p <= x.5, we get ceiling(p - 0.5) = x, and for all x+1 => p > x.5, we get ceiling(p - 0.5) = x+1. This should be exactly what you want.

烟酒忠诚 2024-12-06 22:57:01

您可以使用 preg_replace 来实现此目的:

$string = '1.895';
$pattern = '/(\d+).(\d+)/e';
$replacement = "'\\1'.'.'.((substr($string, -1) > 5) ?  (substr('\\2',0,2) + 1)  :  substr('\\2',0,2))";
echo preg_replace($pattern, $replacement, $string);

You can use the preg_replace for this:

$string = '1.895';
$pattern = '/(\d+).(\d+)/e';
$replacement = "'\\1'.'.'.((substr($string, -1) > 5) ?  (substr('\\2',0,2) + 1)  :  substr('\\2',0,2))";
echo preg_replace($pattern, $replacement, $string);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文