Supprimer les chiffres zéro inutiles des décimales en PHP


164

J'essaie de trouver un moyen rapide de supprimer zero decimalsdes valeurs numériques comme ceci:

echo cleanNumber('125.00');
// 125

echo cleanNumber('966.70');
// 966.7

echo cleanNumber(844.011);
// 844.011

Existe-t-il un moyen optimisé de le faire?


4
Comme vos valeurs sont en fait des chaînes, pourquoi ne pas simplement utiliser rtrim () - php.net/manual/en/function.rtrim.php - avec un «0». comme deuxième argument
Mark Baker

Désolé, je n'ai pas été tout à fait clair, ce ne sont pas toujours des chaînes, je corrige la question.
vitto le

9
@Mark Baker: c'est une mauvaise approche car le numéro 120 sera
ramené

@machineaddict - ce serait si, et seulement si, les valeurs de chaîne n'avaient pas de point décimal ..... toutes celles citées par l'OP ont un point décimal.
Mark Baker le

2
Ensuite, vous devez ajouter une note en gras dans votre réponse, indiquant que cela ne fonctionne que s'il y a des décimales.
machineaddict le

Réponses:


354

$num + 0 fait l'affaire.

echo 125.00 + 0; // 125
echo '125.00' + 0; // 125
echo 966.70 + 0; // 966.7

En interne, cela équivaut à lancer pour flotter avec (float)$numou floatval($num)mais je trouve cela plus simple.


45
je pense que c'est un sale tour. Je ne le préférerais pas car le code ne raconte pas son comportement comme le floatval()fait.
ESCOBAR

4
floatvalLe comportement de @ESCOBAR renvoie un float. Je dirais que l'utiliser comme formateur de décimales n'est pas non plus très évident ou propre.
lafor

2
Ceci est très peu clair. Notre équipe vient de rencontrer cela dans notre code, et 3 développeurs sont perplexes pendant un certain temps. Je pense que la réponse de Mark est une meilleure alternative. Il est plus long, mais son intention est claire.
jfbalanc

2
@jfbalanc//COMMENT
Webinan

1
@ESCOBAR Pas vraiment, c'est une méthode officiellement suggérée pour le typage ... recherche "type jonglage" sur php.net
Gergely Lukacsy

101

vous pouvez simplement utiliser la floatvalfonction

echo floatval('125.00');
// 125

echo floatval('966.70');
// 966.7

echo floatval('844.011');
// 844.011

2
il échoue lorsque le séparateur des milliers est un point et que la marque décimale est une virgule.
Munna Khan

20

Voici ce que j'utilise:

function TrimTrailingZeroes($nbr) {
    return strpos($nbr,'.')!==false ? rtrim(rtrim($nbr,'0'),'.') : $nbr;
}

NB Cela suppose qu'il .s'agit du séparateur décimal. Il a l'avantage de fonctionner sur des nombres arbitrairement grands (ou petits) car il n'y a pas de flotteur. Il ne transformera pas non plus les nombres en notation scientifique (par exemple 1.0E-17).


ce n'est pas une solution sûre, que se passe-t-il si le prix n'est pas décimal? Par exemple, si le développeur multiplie le prix par un entier, nous avons un entier
amin

@alex Cette fonction fonctionne sur les entiers, les flottants et les chaînes.
mpen le

1
Solution parfaite comme aide pour bcmath
Kart Av1k

17

Le simple fait d'ajouter +à votre variable de chaîne provoquera le typage (float) et supprimera les zéros:

var_dump(+'125.00');     // double(125)
var_dump(+'966.70');     // double(966.7)
var_dump(+'844.011');    // double(844.011)
var_dump(+'844.011asdf');// double(844.011)

13

Pour tout le monde qui vient sur ce site ayant le même problème avec les virgules, changez:

$num = number_format($value, 1, ',', '');

à:

$num = str_replace(',0', '', number_format($value, 1, ',', '')); // e.g. 100,0 becomes 100


S'il y a deux zéros à supprimer, passez à:

$num = str_replace(',00', '', number_format($value, 2, ',', '')); // e.g. 100,00 becomes 100

Plus ici: Numéro PHP: point décimal visible uniquement si nécessaire


10

Si vous souhaitez supprimer les chiffres zéro juste avant pour les afficher sur la page ou le modèle.

Vous pouvez utiliser le sprintf () fonction

sprintf('%g','125.00');
//125

‌‌sprintf('%g','966.70');
//966.7

‌‌‌‌sprintf('%g',844.011);
//844.011

Merci j'ai adoré cette réponse. Ceci est très utile pour moi.
Sumit Kumar Gupta

9

Vous devez lancer vos numéros sous forme de flotteurs, ce qui le fera pour vous.

$string = "42.422005000000000000000000000000";
echo (float)$string;

La sortie de ce sera ce que vous recherchez.

42,422005


1
La diffusion flottante peut également corrompre votre numéro. (float)'0.1234567890124567890123456789'devient par exemple 0.12345678901246.
mpen le

8
$x = '100.10'; 
$x = preg_replace("/\.?0*$/",'',$x); 
echo $x;

Il n'y a rien qui ne puisse être corrigé avec une simple regex;)

http://xkcd.com/208/


1
Supprime les 0s significatifs tels que in "100". Échoue également à enlever les 0s "100.010".
mpen le

2
Tout le monde recule! $x = preg_replace("/(\.0*$)|((?<=\.\d*)0+$)/",'',$x);
Emanuel S.

5

Transformé en format float.

$int = 4.324000;
$int = (float) $int;

2

En raison de cette question est ancienne. Tout d'abord, je suis désolé pour ça.

La question porte sur le numéro xxx.xx, mais dans le cas où il s'agit de x, xxx.xxxxx ou d'un séparateur décimal de différence tel que xxxx, xxxx, cela peut être plus difficile à trouver et à supprimer zéro chiffre de la valeur décimale.

/**
 * Remove zero digits from decimal value.
 * 
 * @param string|int|float $number The number can be any format, any where use in the world such as 123, 1,234.56, 1234.56789, 12.345,67, -98,765.43
 * @param string The decimal separator. You have to set this parameter to exactly what it is. For example: in Europe it is mostly use "," instead of ".".
 * @return string Return removed zero digits from decimal value.
 */
function removeZeroDigitsFromDecimal($number, $decimal_sep = '.')
{
    $explode_num = explode($decimal_sep, $number);
    if (is_array($explode_num) && isset($explode_num[count($explode_num)-1]) && intval($explode_num[count($explode_num)-1]) === 0) {
        unset($explode_num[count($explode_num)-1]);
        $number = implode($decimal_sep, $explode_num);
    }
    unset($explode_num);
    return (string) $number;
}

Et voici le code pour le test.

$numbers = [
    1234,// 1234
    -1234,// -1234
    '12,345.67890',// 12,345.67890
    '-12,345,678.901234',// -12,345,678.901234
    '12345.000000',// 12345
    '-12345.000000',// -12345
    '12,345.000000',// 12,345
    '-12,345.000000000',// -12,345
];
foreach ($numbers as $number) {
    var_dump(removeZeroDigitsFromDecimal($number));
}


echo '<hr>'."\n\n\n";


$numbers = [
    1234,// 12324
    -1234,// -1234
    '12.345,67890',// 12.345,67890
    '-12.345.678,901234',// -12.345.678,901234
    '12345,000000',// 12345
    '-12345,000000',// -12345
    '12.345,000000',// 12.345
    '-12.345,000000000',// -12.345
    '-12.345,000000,000',// -12.345,000000 STRANGE!! but also work.
];
foreach ($numbers as $number) {
    var_dump(removeZeroDigitsFromDecimal($number, ','));
}

2

Soyez prudent en ajoutant +0.

echo number_format(1500.00, 2,".",",")+0;
//1

Le résultat est 1.

echo floatval('1,000.00');
// 1

echo floatval('1000.00');
//1000

Vous répondez à une question de 2013.
VTodorov

3
Ce n'est pas un problème de répondre à une vieille question, si cela peut aider les lecteurs réels
Reign.85

1

Etrange, quand j'obtiens un numéro de la base de données avec un type "float" et si mon numéro est ex. 10000 quand je le floatval, il devient 1.

$number = $ad['price_month']; // 1000 from the database with a float type
echo floatval($number);
Result : 1

J'ai testé toutes les solutions ci-dessus mais je n'ai pas fonctionné.


1
$str = 15.00;
$str2 = 14.70;
echo rtrim(rtrim(strval($str), "0"), "."); //15
echo rtrim(rtrim(strval($str2), "0"), "."); //14.7

0

Manière compliquée mais fonctionne:

$num = '125.0100';
$index = $num[strlen($num)-1];
$i = strlen($num)-1;
while($index == '0') {
   if ($num[$i] == '0') {
     $num[$i] = '';
     $i--;
   }

   $index = $num[$i];
}

//remove dot if no numbers exist after dot
$explode = explode('.', $num);
if (isset($explode[1]) && intval($explode[1]) <= 0) {
   $num = intval($explode[0]);
}

echo $num; //125.01

les solutions ci-dessus sont la manière optimale, mais au cas où vous voudriez avoir la vôtre, vous pouvez l'utiliser. Ce que fait cet algorithme, il commence à la fin de la chaîne et vérifie si son 0 , s'il est défini sur une chaîne vide, puis passe au caractère suivant en arrière jusqu'à ce que le dernier caractère soit > 0



0

C'est ma petite solution ... Peut être inclus dans une classe et définir des variables

privé $ dsepparator = '.'; // décimales privées $ tsepparator = ','; // mille

Cela peut être défini par le constructeur et changer pour la langue des utilisateurs.

class foo
{
    private $dsepparator;
    private $tsepparator;

    function __construct(){
        $langDatas = ['en' => ['dsepparator' => '.', 'tsepparator' => ','], 'de' => ['dsepparator' => ',', 'tsepparator' => '.']];
        $usersLang = 'de'; // set iso code of lang from user
        $this->dsepparator = $langDatas[$usersLang]['dsepparator'];
        $this->tsepparator = $langDatas[$usersLang]['tsepparator'];
    }

    public function numberOmat($amount, $decimals = 2, $hideByZero = false)
    {
        return ( $hideByZero === true AND ($amount-floor($amount)) <= 0 ) ? number_format($amount, 0, $this->dsepparator, $this->tsepparator) : number_format($amount, $decimals, $this->dsepparator, $this->tsepparator);
    }
    /*
     * $bar = new foo();
     * $bar->numberOmat('5.1234', 2, true); // returns: 5,12
     * $bar->numberOmat('5', 2); // returns: 5,00
     * $bar->numberOmat('5.00', 2, true); // returns: 5
     */

}

J'ai donc construit une classe d'échantillon avec de petits échantillons. Mieux? =)
Paykoman

0

C'est ma solution. Je souhaite conserver la possibilité d'ajouter un séparateur de milliers

    $precision = 5;    
    $number = round($number, $precision);
    $decimals = strlen(substr(strrchr($number, '.'), 1));
    return number_format($number, $precision, '.', ',');

0

Il s'agit d'une simple fonction d'une ligne utilisant rtrim, enregistrer le séparateur et le point décimal:

function myFormat($num,$dec)
 {
 return rtrim(rtrim(number_format($num,$dec),'0'),'.');
 }

0

J'ai trouvé que cette solution est la meilleure:

public function priceFormat(float $price): string
{
    //https://stackoverflow.com/a/14531760/5884988
    $price = $price + 0;
    $split = explode('.', $price);
    return number_format($price, isset($split[1]) ? strlen($split[1]) : 2, ',', '.');
}

0

Simple et précis!

function cleanNumber($num){
    $explode = explode('.', $num);
    $count   = strlen(rtrim($explode[1],'0'));
    return bcmul("$num",'1', $count);
}

0

Solution ultime: le seul moyen sûr est d'utiliser regex:

echo preg_replace("/\.?0+$/", "", 3.0); // 3
echo preg_replace("/\d+\.?\d*(\.?0+)/", "", 3.0); // 3

cela fonctionnera dans tous les cas


0

Ce qui suit est beaucoup plus simple

if(floor($num) == $num) {
    echo number_format($num);
} else {
    echo $num;
}

-1
$value = preg_replace('~\.0+$~','',$value);

1
Cela améliorerait la qualité de votre réponse si vous expliquiez ce que fait votre code et comment il résoudra la question d'origine.
Nigel Ren

@Nikhil Gyan Je suis d'accord que cette réponse n'est pas géniale. N'hésitez pas à noter. Cependant, au moins je ne pense pas que ce soit assez mauvais pour un drapeau de très faible qualité
Sam Hartman

-2

Ce code supprimera zéro après point et ne renverra que deux chiffres décimaux.

$ nombre = 1200,0000;
str_replace ('. 00', '', number_format ($ nombre, 2, '.', ''));

La sortie sera: 1200

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.