2011-08-18 57 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; 
}