Entfernen Sie unbrauchbare Nullstellen von Dezimalstellen in PHP


163

Ich versuche einen schnellen Weg zu finden, um solche zero decimalsZahlenwerte zu entfernen :

echo cleanNumber('125.00');
// 125

echo cleanNumber('966.70');
// 966.7

echo cleanNumber(844.011);
// 844.011

Gibt es eine optimierte Möglichkeit, dies zu tun?


4
Da Ihre Werte tatsächlich Zeichenfolgen sind, verwenden Sie einfach rtrim () - php.net/manual/en/function.rtrim.php - mit einer '0'. als zweites Argument
Mark Baker

Entschuldigung, ich war nicht ganz klar, es sind nicht immer Zeichenfolgen, ich behebe die Frage.
Vitto

9
@ Mark Baker: Das ist ein schlechter Ansatz, da Nummer 120 auf 12
gekürzt wird

@machineaddict - es wäre genau dann, wenn die Zeichenfolgenwerte keinen Dezimalpunkt hätten ..... alle vom OP zitierten Werte hätten einen Dezimalpunkt.
Mark Baker

2
Dann sollten Sie Ihrer Antwort einen fetten Hinweis hinzufügen, dass dies nur funktioniert, wenn Dezimalstellen vorhanden sind.
Machineaddict

Antworten:


352

$num + 0 macht den Trick.

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

Intern entspricht dies dem Gießen zum Schweben (float)$num oderfloatval($num) aber ich finde es einfacher.


45
Ich denke, das ist ein schmutziger Trick. Ich würde es nicht bevorzugen, weil der Code nicht über sein Verhalten sagt, wie floatval()es tut.
ESCOBAR

4
Das floatvalVerhalten von @ESCOBAR gibt einen Float zurück. Ich würde argumentieren, dass die Verwendung als Dezimalformatierer auch nicht sehr offensichtlich oder sauber ist.
Für den

2
Dies ist sehr unklar. Unser Team hat dies gerade in unserem Code festgestellt und 3 Entwickler waren einige Zeit verwirrt. Ich denke, Marks Antwort ist eine bessere Alternative. Es ist länger, aber seine Absicht ist klar.
jfbalanc

2
@jfbalanc//COMMENT
Webinan

1
@ESCOBAR Nicht wirklich, es ist eine offiziell vorgeschlagene Methode für Typografie ... Suche "Typ Jonglieren" auf php.net
Gergely Lukacsy

101

Sie könnten einfach die floatvalFunktion verwenden

echo floatval('125.00');
// 125

echo floatval('966.70');
// 966.7

echo floatval('844.011');
// 844.011

2
Es schlägt fehl, wenn das Tausendertrennzeichen ein Punkt und die Dezimalstelle ein Komma ist.
Munna Khan

20

Das benutze ich:

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

Hinweis: Dies setzt .das Dezimaltrennzeichen voraus . Es hat den Vorteil, dass es mit beliebig großen (oder kleinen) Zahlen funktioniert, da es keinen Float Cast gibt. Es werden auch keine Zahlen in wissenschaftliche Notation umgewandelt (z. B. 1.0E-17).


Dies ist keine sichere Lösung. Was ist, wenn der Preis nicht dezimal ist? Wenn Entwickler beispielsweise den Preis mit einer Ganzzahl multiplizieren, haben wir eine Ganzzahl
am

@alex Diese Funktion funktioniert für Ganzzahlen, Gleitkommazahlen und Zeichenfolgen.
Mpen

1
Perfekte Lösung als Helfer für bcmath
Kart Av1k

17

Durch einfaches Hinzufügen +zu Ihrer Zeichenfolgenvariablen wird typecast (float) ausgeführt und Nullen entfernt:

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

Für alle, die auf diese Site kommen und stattdessen das gleiche Problem mit Kommas haben, ändern Sie Folgendes:

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

zu:

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


Wenn zwei Nullen entfernt werden müssen, wechseln Sie zu:

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

Mehr hier: PHP-Nummer: Dezimalpunkt nur bei Bedarf sichtbar


10

Wenn Sie die Nullstellen kurz zuvor entfernen möchten, um sie auf der Seite oder Vorlage anzuzeigen.

Sie können die Funktion sprintf () verwenden

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

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

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

Danke, ich habe diese Antwort geliebt. Das ist sehr hilfreich für mich.
Sumit Kumar Gupta

9

Sie sollten Ihre Zahlen als Floats ausgeben, was dies für Sie erledigt.

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

Die Ausgabe davon wird das sein, wonach Sie suchen.

42.422005


1
Float Casting kann auch Ihre Nummer beschädigen. zB (float)'0.1234567890124567890123456789'wird 0.12345678901246.
Mpen

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

Es gibt nichts, was mit einem einfachen regulären Ausdruck nicht behoben werden kann;)

http://xkcd.com/208/


1
Entfernt wichtige 0s wie in "100". Kann auch nicht 0s abstreifen "100.010".
Mpen

2
Alle treten zurück! $x = preg_replace("/(\.0*$)|((?<=\.\d*)0+$)/",'',$x);
Emanuel S.


2

Aufgrund dieser Frage ist alt. Erstens tut mir das leid.

Die Frage bezieht sich auf die Zahl xxx.xx, aber falls es sich um x, xxx.xxxxx oder ein Differenz-Dezimaltrennzeichen wie xxxx, xxxx handelt, kann es schwieriger sein, Nullstellen vom Dezimalwert zu finden und zu entfernen.

/**
 * 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;
}

Und hier ist der Code zum Testen.

$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

Seien Sie vorsichtig beim Hinzufügen von +0.

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

Ergebnis ist 1.

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

echo floatval('1000.00');
//1000

Sie beantworten eine Frage von 2013.
VTodorov

3
Es ist kein Problem, eine alte Frage zu beantworten, wenn es tatsächlichen Lesern helfen kann
Reign.85

1

Seltsam, wenn ich eine Nummer aus der Datenbank mit dem Typ "float" bekomme und wenn meine Nummer ex ist. 10000 wenn ich es schwebe, wird es 1.

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

Ich habe alle oben genannten Lösungen getestet, aber nicht funktioniert.


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

0

Komplizierter Weg, funktioniert aber:

$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

Die oben genannten Lösungen sind der optimale Weg, aber falls Sie Ihre eigenen haben möchten, können Sie diese verwenden. Was dieser Algorithmus tut, beginnt am Ende der Zeichenfolge und prüft, ob seine 0 ist. Wenn dies der Fall ist, wird die Zeichenfolge auf leer gesetzt und geht dann von hinten zum nächsten Zeichen, bis das letzte Zeichen > 0 ist



0

Das ist meine kleine Lösung ... Kann in eine Klasse aufgenommen werden und vars setzen

private $ dsepparator = '.'; // Dezimalstellen private $ tsepparator = ','; // tausend

Dies kann vom Konstruktor festgelegt und in Benutzer lang geändert werden.

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
     */

}

Also habe ich eine Beispielklasse mit kleinen Beispielen erstellt. Besser? =)
Paykoman

0

Das ist meine Lösung. Ich möchte die Möglichkeit behalten, Tausende Trennzeichen hinzuzufügen

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

0

Dies ist eine einfache einzeilige Funktion mit rtrim, Save Separator und Dezimalpunkt:

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

0

Ich fand diese Lösung die beste:

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

Einfach und genau!

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

0

Ultimative Lösung: Der einzig sichere Weg ist die Verwendung von Regex:

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

es wird auf jeden Fall funktionieren


0

Das Folgende ist viel einfacher

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

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

1
Es würde die Qualität Ihrer Antwort verbessern, wenn Sie erklären würden, was Ihr Code tut und wie er die ursprüngliche Frage löst.
Nigel Ren

@ Nikil Gyan Ich stimme zu, diese Antwort ist nicht großartig. Fühlen Sie sich frei zu tun. Allerdings denke ich zumindest nicht, dass es schlecht genug für eine Flagge von sehr geringer Qualität ist
Sam Hartman

-2

Dieser Code entfernt Null nach Punkt und gibt nur zwei Dezimalstellen zurück.

$ number = 1200.0000;
str_replace ('. 00', '', number_format ($ number, 2, '.', ''));

Die Ausgabe wird sein: 1200

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.