web-dev-qa-db-fra.com

PHP Comment arrondir à deux décimales?

Je dois arrondir une décimale dans PHP à deux décimales pour que:

49.955

devient...

49.95

J'ai essayé number_format , mais cela arrondit simplement la valeur à 49.96 . Je ne peux pas utiliser substr car le nombre peut être plus petit (comme 7,950). Je n'ai pas trouvé de réponse à cette question jusqu'à présent.

Toute aide très appréciée.

36
Adam Moss

Cela peut fonctionner: floor($number * 100) / 100

74
GeoffreyB

Voici une fonction intéressante qui fait l'affaire sans utiliser de fonctions de chaîne:

<?php
function floorp($val, $precision)
{
    $mult = pow(10, $precision); // Can be cached in lookup table        
    return floor($val * $mult) / $mult;
}

print floorp(49.955, 2);
?>

Une autre option consiste à soustraire une fraction avant d’arrondir:

function floorp($val, $precision)
{
    $half = 0.5 / pow(10, $precision); // Can be cached in a lookup table
    return round($val - $half, $precision);
}
20
huysentruitw

Malheureusement, aucune des réponses précédentes (y compris celle acceptée) ne fonctionne pour toutes les entrées possibles.

1) sprintf('%1.'.$precision.'f', $val)

Échec avec une précision de 2: 14,239 devrait renvoyer 14,23 (mais dans ce cas, renvoie 14,24).

2) floatval(substr($val, 0, strpos($val, '.') + $precision + 1))

Échec avec une précision de 0: 14 devrait renvoyer 14 (mais dans ce cas, renvoie 1)

3) substr($val, 0, strrpos($val, '.', 0) + (1 + $precision))

Échec avec une précision de 0: -1 devrait renvoyer -1 (mais dans ce cas, retourne '-')

4) floor($val * pow(10, $precision)) / pow(10, $precision)

Bien que j'aie beaucoup utilisé celui-ci, j'ai récemment découvert une faille dans celui-ci; cela échoue aussi pour certaines valeurs. Avec une précision de 2: 2,05 devrait renvoyer 2,05 (mais dans ce cas renvoie 2,04 !!)

Jusqu'ici, le seul moyen de réussir tous mes tests est malheureusement de manipuler des chaînes. Ma solution basée sur rationalboss one, est la suivante:

function floorDec($val, $precision = 2) {
    if ($precision < 0) { $precision = 0; }
    $numPointPosition = intval(strpos($val, '.'));
    if ($numPointPosition === 0) { //$val is an integer
        return $val;
    }
    return floatval(substr($val, 0, $numPointPosition + $precision + 1));
}

Cette fonction fonctionne avec des nombres positifs et négatifs, ainsi que toute précision requise.

EDIT: Vous pouvez trouver un exemple de travail ici: http://codepad.viper-7.com/ZGprQJ , mais c'est actuellement un lien mort.

15
Alex

Multipliez votre entrée par 100, floor (), puis divisez le résultat par 100. 

6
GordonM

Essayez la fonction round()

Comme ceci: round($num, 2, PHP_ROUND_HALF_DOWN);

2
user1606963
function roundDown($decimal, $precision)
{
    $sign = $decimal > 0 ? 1 : -1;
    $base = pow(10, $precision);
    return floor(abs($decimal) * $base) / $base * $sign;
}

// Examples
roundDown(49.955, 2);           // output: 49.95
roundDown(-3.14159, 4);         // output: -3.1415
roundDown(1000.000000019, 8);   // output: 1000.00000001

Cette fonction fonctionne avec des décimales positives et négatives à toute précision.

Exemple de code ici: http://codepad.org/1jzXjE5L

2
Sterling Beason
function floorToPrecision($val, $precision = 2) {
        return floor(round($val * pow(10, $precision), $precision)) / pow(10, $precision);
    }
1
Yatish Balaji

Je pense qu'il y a un moyen assez simple d'y parvenir:

$rounded = bcdiv($val, 1, $precision);

Voici un exemple de travail . BCMath doit être installé, mais je pense qu’il est normalement fourni avec une installation de PHP. :) Voici la documentation .

1
Jamie Robinson

Utiliser une sortie formatée 

sprintf("%1.2f",49.955) //49.95

D&EACUTE;MO

1

Vous pouvez utiliser:

$num = 49.9555;
echo substr($num, 0, strpos($num, '.') + 3);
0
rationalboss

Si vous voulez arrondir la décimale vers le bas uniquement lorsque la dernière partie est 5 ou plus bas, la meilleure solution consiste à utiliser:

round(4.955,2,PHP_ROUND_HALF_DOWN);

Maintenant, si vous voulez toujours arrondir les décimales vers le bas tout en gardant le contrôle sur le nombre de décimales, la meilleure solution est la suivante:

round(floor(4.957*100)/100,2)

Considérez également que le nombre "100" doit être mis à l'échelle avec la décimale "2". PAR EXEMPLE. Si vous voulez 4 décimales, vous devrez multiplier par 10 000 et diviser par 10 000 pour ne perdre que les nombres au-delà de ce point.

0
Guilherme Ferreira

Vous pouvez utiliser la fonction bcdiv PHP.

bcdiv(49.955, 1, 2)
0
Sanaullah Ahmad

Une solution alternative utilisant regex qui devrait fonctionner pour tous les nombres positifs ou négatifs, entiers ou avec des nombres décimaux:

if (preg_match('/^-?(\d+\.?\d{1,2})\d*$/', $originalValue, $matches)){
    $roundedValue = $matches[1];
} else {
    throw new \Exception('Cannot round down properly '.$originalValue.' to two decimal places');
}
0
Luke Cousins