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?

vitto
la source
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.

lafor
la source
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
DiverseAndRemote.com
la source
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).

mpen
la source
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)
Alexander Yancharuk
la source
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

Kai Noack
la source
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
Hemerson Varela
la source
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

Sajan Parikh
la source
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/

Dakkaron
la source
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;
Joseph A.
la source
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, ','));
}
vee
la source
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
OnionStand
la source
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é.

lio
la source
1
$str = 15.00;
$str2 = 14.70;
echo rtrim(rtrim(strval($str), "0"), "."); //15
echo rtrim(rtrim(strval($str2), "0"), "."); //14.7
RatajS
la source
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

GGio
la source
0

Vous pouvez utiliser:

print (floatval)(number_format( $Value), 2 ) );    
MUNEERPASHA GADAD
la source
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
     */

}
Paykoman
la source
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, '.', ',');
despotbg
la source
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'),'.');
 }
APH
la source
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, ',', '.');
}
Rawburner
la source
0

Simple et précis!

function cleanNumber($num){
    $explode = explode('.', $num);
    $count   = strlen(rtrim($explode[1],'0'));
    return bcmul("$num",'1', $count);
}
J. Doe
la source
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

Yohanes AI
la source
0

Ce qui suit est beaucoup plus simple

if(floor($num) == $num) {
    echo number_format($num);
} else {
    echo $num;
}
Nemrod Mondez
la source
-1
$value = preg_replace('~\.0+$~','',$value);
Nikhil Gyan
la source
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

Ashish Pathak
la source