Hapus nol digit yang tidak berguna dari desimal di PHP

163

Saya mencoba menemukan cara cepat untuk menghapus zero decimalsdari nilai angka seperti ini:

echo cleanNumber('125.00');
// 125

echo cleanNumber('966.70');
// 966.7

echo cleanNumber(844.011);
// 844.011

Apakah ada beberapa cara yang dioptimalkan untuk melakukan itu?

vitto
sumber
4
Karena nilai Anda sebenarnya adalah string, mengapa tidak menggunakan rtrim () - php.net/manual/en/function.rtrim.php - dengan tanda '0.' sebagai argumen kedua
Mark Baker
Maaf, saya belum sepenuhnya jelas, mereka tidak selalu string, saya memperbaiki pertanyaan.
vitto
9
@ Mark Baker: itu adalah pendekatan yang buruk karena nomor 120 akan dipangkas menjadi 12
machineaddict
@machineaddict - itu akan terjadi jika, dan hanya jika, nilai-nilai string tidak memiliki titik desimal ..... semua yang dikutip oleh OP memiliki titik desimal.
Mark Baker
2
Maka Anda harus menambahkan pemberitahuan yang berani dalam jawaban Anda, bahwa itu hanya berfungsi jika ada desimal.
machineaddict

Jawaban:

354

$num + 0 lakukan triknya.

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

Secara internal, ini setara dengan casting untuk mengapung dengan (float)$numatau floatval($num)tetapi saya merasa lebih sederhana.

lafor
sumber
45
Saya pikir ini adalah trik kotor. saya tidak akan suka karena kode tidak memberi tahu perilakunya seperti floatval()melakukannya.
ESCOBAR
4
Perilaku @ESCOBAR floatvaladalah mengembalikan float. Saya berpendapat menggunakannya sebagai formatter desimal tidak terlalu jelas atau bersih.
lafor
2
Ini sangat tidak jelas. Tim kami baru saja menemukan ini dalam kode kami, dan itu membuat 3 pengembang bingung untuk beberapa waktu. Saya pikir jawaban Mark adalah alternatif yang lebih baik. Itu lebih panjang, tetapi niatnya jelas.
jfbalanc
2
@jfbalanc//COMMENT
Webinan
1
@ ESCOBAR Tidak juga, ini adalah metode yang disarankan secara resmi untuk typecasting ... cari "type juggling" di php.net
Gergely Lukacsy
101

Anda bisa menggunakan floatvalfungsi ini

echo floatval('125.00');
// 125

echo floatval('966.70');
// 966.7

echo floatval('844.011');
// 844.011
DiverseAndRemote.com
sumber
2
gagal ketika pemisah seribu adalah titik dan tanda desimal adalah koma.
Munna Khan
20

Inilah yang saya gunakan:

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

NB Asumsi ini .adalah pemisah desimal. Ini memiliki keuntungan bahwa ia akan bekerja pada angka yang besar (atau kecil) semena-mena karena tidak ada pelampung apung. Ini juga tidak akan mengubah angka menjadi notasi ilmiah (misalnya 1.0E-17).

Mpen
sumber
ini bukan solusi yang aman, bagaimana jika harga tidak desimal? misalnya jika pengembang mengalikan harga dengan integer maka kita memiliki integer
amin
@alex Fungsi ini berfungsi pada integer, float, dan string.
mpen
1
Solusi sempurna sebagai penolong untuk bcmath
Kart Av1k
17

Cukup menambahkan +ke variabel string Anda akan menyebabkan typecast menjadi (mengambang) dan menghapus nol:

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
sumber
13

Untuk semua orang yang datang ke situs ini yang memiliki masalah yang sama dengan komata, ubah:

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

untuk:

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


Jika ada dua nol yang akan dihapus, maka ubah ke:

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

Lebih lanjut di sini: Nomor PHP: titik desimal hanya terlihat jika diperlukan

Kai Noack
sumber
10

Jika Anda ingin menghapus digit nol sebelum ditampilkan pada halaman atau templat.

Anda dapat menggunakan sprintf () function

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

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

‌‌‌‌sprintf('%g',844.011);
//844.011
Hemerson Varela
sumber
Terima kasih saya menyukai jawaban ini. Ini sangat membantu saya.
Sumit Kumar Gupta
9

Anda harus memasukkan angka sebagai pelampung, yang akan melakukan ini untuk Anda.

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

Output dari ini akan menjadi apa yang Anda cari.

42.422005

Sajan Parikh
sumber
1
Casting float juga dapat merusak nomor Anda. misalnya (float)'0.1234567890124567890123456789'menjadi 0.12345678901246.
buka
8
$x = '100.10'; 
$x = preg_replace("/\.?0*$/",'',$x); 
echo $x;

Tidak ada yang tidak bisa diperbaiki dengan regex sederhana;)

http://xkcd.com/208/

Dakkaron
sumber
1
Hapus strip signifikan 0seperti pada "100". Juga gagal 0melepas "100.010".
buka
2
Semuanya mundur! $x = preg_replace("/(\.0*$)|((?<=\.\d*)0+$)/",'',$x);
Emanuel S.
5

Typecast ke a float.

$int = 4.324000;
$int = (float) $int;
Joseph A.
sumber
2

Karena pertanyaan ini sudah lama. Pertama, saya minta maaf tentang ini.

Pertanyaannya adalah tentang nomor xxx.xx tetapi jika itu adalah x, xxx.xxxxx atau pemisah desimal perbedaan seperti xxxx, xxxx ini bisa lebih sulit untuk menemukan dan menghapus nol digit dari nilai desimal.

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

Dan ini kode untuk tes.

$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
sumber
2

Hati-hati dengan menambahkan +0.

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

Hasil ini adalah 1.

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

echo floatval('1000.00');
//1000
OnionStand
sumber
Anda menjawab pertanyaan mulai tahun 2013.
VTodorov
3
Ini bukan masalah untuk menjawab pertanyaan lama, jika dapat membantu pembaca yang sebenarnya
Pemerintahan.85
1

Aneh, ketika saya mendapatkan nomor dari database dengan tipe "float" dan jika nomor saya mantan. 10.000 ketika saya mengapung, itu menjadi 1.

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

Saya sudah menguji semua solusi di atas tetapi tidak berhasil.

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

Cara rumit tetapi berfungsi:

$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

solusi di atas adalah cara optimal tetapi jika Anda ingin memiliki Anda sendiri, Anda bisa menggunakan ini. Apa yang dilakukan algoritma ini dimulai pada akhir string dan memeriksa apakah 0 , jika diset ke string kosong dan kemudian beralih ke karakter berikutnya dari belakang hingga karakter terakhir adalah > 0

GGio
sumber
0

Kamu bisa memakai:

print (floatval)(number_format( $Value), 2 ) );    
MUNEERPASHA GADAD
sumber
0

Itulah solusi kecil saya ... Dapat dimasukkan ke kelas dan mengatur vars

private $ dsepparator = '.'; // desimal pribadi $ tsepparator = ','; // ribu

Itu dapat diatur oleh konstruktor dan diubah ke pengguna lang.

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
sumber
Jadi saya telah membangun kelas sampel dengan sampel kecil. Lebih baik? =)
Paykoman
0

Ini solusi saya. Saya ingin menjaga kemampuan untuk menambahkan ribuan pemisah

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

Ini adalah fungsi satu garis sederhana menggunakan rtrim, save separator dan titik desimal:

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

Saya menemukan solusi ini adalah yang terbaik:

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
sumber
0

Sederhana dan akurat!

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

Solusi Utama: Satu-satunya cara aman adalah menggunakan regex:

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

itu akan bekerja untuk kasus apa pun

Yohanes AI
sumber
0

Berikut ini jauh lebih sederhana

if(floor($num) == $num) {
    echo number_format($num);
} else {
    echo $num;
}
Nemrod Mondez
sumber
-1
$value = preg_replace('~\.0+$~','',$value);
Nikhil Gyan
sumber
1
Ini akan meningkatkan kualitas jawaban Anda jika Anda memberikan penjelasan tentang apa yang kode Anda lakukan dan bagaimana hal itu akan menyelesaikan pertanyaan awal.
Nigel Ren
@Nikhil Gyan Saya setuju jawaban ini tidak bagus. Jangan ragu untuk menulis. Namun, saya setidaknya tidak berpikir itu cukup buruk untuk bendera berkualitas sangat rendah
Sam Hartman
-2

Kode ini akan menghapus nol setelah titik dan hanya akan mengembalikan dua digit desimal.

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

Output akan menjadi: 1200

Pathak Ashish
sumber