2011-08-18 41 views
3

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

基本思想是1.895变成1.89,而不是像圆通常那样的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, '.', ''); 
} 

回答

2

可以起飞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,我们得到ceiling(p - 0.5)= x,对于al l x + 1 => p> x.5,我们得到上限(p - 0.5)= x + 1。这应该是你想要的。

+0

谢谢,它似乎工作,但我需要做一些真实的测试,因为在某些情况下,它会产生与Joseph的功能不同的结果。 – ragulka

+0

什么示例:)? – MGwynne

+0

好吧,看起来这个功能差不多就是我所需要的,但是,由于一些奇怪的原因,有时它会将1.825调整到1.83。这似乎是PHP的一个错误 - 当提供的数字是计算结果(例如1.326 - 0.001)时,它会将其提高到1.83。当数字是以字符串的形式提供的(之前没有进行过任何计算,它可以正常工作,我通过在函数的开始处添加这些行来修复它: '$ v = explode('。',$ v); $ v = implode('。',$ v);' – ragulka

6

您可以通过简单地转换成字符串欺骗和备份:

$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); 
} 
+0

它可以使用4位小数吗?像1.9651? – ragulka

+0

当然,为什么不呢?自己试试! –

+0

@ragulka:我将代码添加为一个函数。用几个数字试试吧...... –

0

可以使用此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); 
+1

然而,这只会截断数字在2位小数,而我们想要例如1.896四舍五入到1.90 – Mchl

+0

我的错误:(。我编辑它:) – munjal

3

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