PHP'deki ondalık sayılardan işe yaramaz sıfır basamağını kaldırma


163

Bunun zero decimalsgibi sayı değerlerinden kaldırmak için hızlı bir yol bulmaya çalışıyorum :

echo cleanNumber('125.00');
// 125

echo cleanNumber('966.70');
// 966.7

echo cleanNumber(844.011);
// 844.011

Bunu yapmak için optimize edilmiş bir yol var mı?


4
Değerleriniz aslında dizgiler olduğundan, neden '0' ile rtrim () - php.net/manual/en/function.rtrim.php - kullanmıyorsunuz ? ikinci argüman olarak
Mark Baker

Üzgünüm, tamamen net değilim, onlar her zaman ipler değil, soruyu düzeltirim.
vitto

9
@Mark Baker: 120 sayısı 12'ye düşürüleceğinden bu kötü bir yaklaşım
machineaddict

@machineaddict - yalnızca ve dize değerlerinde ondalık noktası yoksa ..... olur. OP tarafından belirtilenlerin ondalık noktası olur.
Mark Baker

2
O zaman cevabınıza sadece ondalık varsa işe yarayacağına dair cesur bir uyarı eklemelisiniz.
machineaddict

Yanıtlar:


354

$num + 0 hile yapar.

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

Dahili olarak, bu şamandıra ile dökmeye eşdeğerdir (float)$numveya floatval($num)daha basit buluyorum.


45
bence bu kirli bir numara. kod gibi davranıyor hakkında anlatmıyor çünkü bunu tercih floatval()etmem.
ESCOBAR

4
@ESCOBAR'ın floatvaldavranışı bir şamandıra döndürüyor. Ben de ondalık biçimlendirici olarak çok tartışmasız ya da temiz olarak kullanarak tartışmak.
lafor

2
Bu çok belirsiz. Ekibimiz kodumuzda bu sorunla karşılaştı ve 3 geliştiricinin bir süre şaşkınlığı vardı. Bence Mark'ın cevabı daha iyi bir alternatif. Daha uzun, ama amacı açık.
jfbalanc

2
@jfbalanc//COMMENT
Webinan

1
@ESCOBAR Gerçekten değil, bu tipik bir daktilo için bir yöntem ...
php.net

101

sadece floatvalfonksiyonu kullanabilirsiniz

echo floatval('125.00');
// 125

echo floatval('966.70');
// 966.7

echo floatval('844.011');
// 844.011

2
binlik ayırıcı nokta ve ondalık işareti virgül olduğunda başarısız olur.
Munna Khan

20

Ne kullanıyorum:

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

NB Bu ., ondalık ayırıcı olduğunu varsayar . Şamandıra dökümü olmadığı için keyfi olarak büyük (veya küçük) sayılar üzerinde çalışacağı avantajına sahiptir. Ayrıca sayıları bilimsel gösterime dönüştürmez (örneğin 1.0E-17).


Bu güvenli bir çözüm değildir, ya fiyat ondalık değilse? Örneğin, geliştirici fiyatı bir tamsayı ile çarparsa, bir tamsayıya sahibiz
amin

@alex Bu işlev tamsayılar, kayan noktalar ve dizgiler üzerinde çalışır.
1616'da

1
Bcmath için yardımcı olarak mükemmel çözüm
Kart Av1k

17

Basitçe +dize değişkeninize eklemek typecast'e (float) neden olur ve sıfırları kaldırır:

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

Bu siteye virgülle aynı sorunu yaşayan herkes için şunu değiştirin:

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

için:

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


Varsa iki sıfırlar kaldırılacak, ardından değiştirin:

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

Daha fazla burada: PHP numarası: ondalık nokta yalnızca gerekirse görünür


10

Sıfır basamakları sayfada veya şablonda görüntülenmeden hemen önce kaldırmak istiyorsanız.

Sen kullanabilirsiniz sprintf () fonksiyonu

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

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

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

Teşekkürler bu cevabı sevdim. Bu benim için çok faydalı.
Sumit Kumar Gupta

9

Sayılarınızı yüzer olarak atamalısınız, bu da bunu sizin için yapacak.

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

Bunun çıktısı aradığınız şey olacaktır.

42.422005


1
Şamandıra döküm de numaranızı bozabilir. örneğin (float)'0.1234567890124567890123456789'olur 0.12345678901246.
mpen

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

Basit bir normal ifade ile düzeltilemeyen hiçbir şey yoktur;)

http://xkcd.com/208/


1
0Gibi önemli s şeritler "100". Ayrıca şerit 0kopmaz "100.010".
mpen

2
Herkes geri çekilsin! $x = preg_replace("/(\.0*$)|((?<=\.\d*)0+$)/",'',$x);
Emanuel S.

5

Bir üzere Typecast float.

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

2

Bu soru nedeniyle eski. İlk olarak, bunun için üzgünüm.

Soru, xxx.xx sayısı hakkındadır, ancak x, xxx.xxxxx veya xxxx, xxxx gibi fark ondalık ayırıcı olması durumunda, ondalık değerden sıfır basamak bulmak ve kaldırmak daha zor olabilir.

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

Ve işte test kodu.

$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

+0 eklerken dikkatli olun.

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

Bunun sonucu 1'dir.

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

echo floatval('1000.00');
//1000

2013'ten bir soru cevaplıyorsunuz.
VTodorov

3
Gerçek okuyuculara yardımcı olabilirse eski bir soruyu cevaplamak sorun değil
Reign.85

1

Garip, bir "float" türü ile veritabanından bir sayı almak ve benim numara eski ise. Ben yüzdüğümde 10000, 1 olur.

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

Yukarıdaki tüm çözümleri test ettim ama işe yaramadı.


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

0

Karmaşık bir yol ama işe yarıyor:

$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

yukarıdaki çözümler en uygun yoldur, ancak kendinize ait olmak istiyorsanız bunu kullanabilirsiniz. Bu algoritma, dizenin sonunda başlar ve boş dizeye ayarlanmışsa ve son karakter > 0 olana kadar arkadan sonraki karaktere giderse , 0'ın olup olmadığını kontrol eder.



0

Bu benim küçük çözümüm ... Bir sınıfa dahil edilebilir ve set vars olabilir

private $ dsepparator = '.'; // ondalık sayılar private $ tsepparator = ','; // bin

Bu, kurucu tarafından ayarlanabilir ve kullanıcı diline değiştirilebilir.

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

}

Yani küçük örnekler ile bir örnek sınıf inşa var. Daha iyi? =)
Paykoman

0

Bu benim çözümüm. Binlerce ayırıcı ekleme yeteneğini korumak istiyorum

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

0

Bu, rtrim, ayırıcıyı ve ondalık noktasını kullanarak basit bir satır işlevidir:

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

0

Bu çözümü en iyi buldum:

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

Basit ve doğru!

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

0

Nihai Çözüm: Tek güvenli yol regex kullanmaktır:

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

her durumda çalışacak


0

Aşağıdakiler çok daha basit

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

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

1
Kodunuzun ne yaptığını ve orijinal soruyu nasıl çözeceğini açıklarsanız, yanıtınızın kalitesini artıracaktır.
Nigel Ren

@Nikhil Gyan Bu cevabın harika olmadığını kabul ediyorum. Yemekten çekinmeyin. Ancak, en azından çok düşük kaliteli bayrak için yeterince kötü olduğunu düşünmüyorum
Sam Hartman

-2

Bu Kod noktadan sonra sıfırı kaldıracak ve yalnızca iki ondalık basamak döndürecektir.

$ sayı 1200.0000 =;
str_replace ('. 00', '', sayı_format ($ sayı, 2, '.', ''));

Çıktı: 1200

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.