Видаліть непотрібні нульові цифри з десяткових знаків у PHP


163

Я намагаюся знайти швидкий спосіб видалити zero decimalsз таких значень чисел:

echo cleanNumber('125.00');
// 125

echo cleanNumber('966.70');
// 966.7

echo cleanNumber(844.011);
// 844.011

Чи існує якийсь оптимізований спосіб зробити це?


4
Оскільки ваші значення насправді є рядками, чому б просто не використовувати rtrim () - php.net/manual/en/function.rtrim.php - із символом "0." як другий аргумент
Марк Бейкер

Вибачте, я не зовсім зрозуміла, вони не завжди є рядками, і я вирішую питання.
vitto

9
@ Марк Бейкер: це поганий підхід, оскільки число 120 буде порізане на 12
машинобудівний вирок

@machineaddict - це було б, і якщо тільки рядкові значення не мали десяткової крапки ..... всі, які цитуються в ОП, мають десяткову точку.
Марк Бейкер

2
Тоді вам слід додати сміливе повідомлення у своїй відповіді, що воно працює лише у випадку десяткових знаків.
машинобудівний вирок

Відповіді:


354

$num + 0 робить трюк.

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

Внутрішньо це еквівалентно литтю, що плаває, (float)$numабо floatval($num)я вважаю простішим.


45
Я думаю, це брудна хитрість. я б не віддав перевагу тому, що код не розповідає про його поведінку, як floatval()це робиться.
ESCOBAR

4
Поведінка @ESCOBAR floatvalповертає поплавок. Я б заперечував, що його використання як десятковий формат також не дуже очевидно чи чисто.
lafor

2
Це дуже незрозуміло. Наша команда щойно стикалася з цим у нашому коді, і це було тривалий час, коли 3 розробника спантеличено. Я думаю , що відповідь Марка - краща альтернатива. Він довший, але його намір зрозумілий.
jfbalanc

2
@jfbalanc//COMMENT
Вебінан

1
@ESCOBAR Насправді це не офіційно запропонований метод для набору клавіш ... пошук "типу жонглювання" на php.net
Гергелій Лукачсі

101

ви могли просто скористатися floatvalфункцією

echo floatval('125.00');
// 125

echo floatval('966.70');
// 966.7

echo floatval('844.011');
// 844.011

2
він не вдається, коли роздільник тисяч є крапкою, а десяткова позначка - комою.
Мунна Хан

20

Це те, що я використовую:

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

Примітка. Це передбачає .десятковий роздільник. Він має перевагу в тому, що він буде працювати на довільно великих (або малих) числах, оскільки немає плаваючого складу. Він також не перетворить числа в наукові позначення (наприклад, 1.0E-17).


це не безпечне рішення, що робити, якщо ціна не десяткова? Наприклад, якщо розробник помножить ціну на ціле число, то у нас є ціле число
амін

@alex Ця функція працює на цілі числа, плавці та рядки.
1616 року

1
Ідеальне рішення як помічник для bcmath
Kart Av1k

17

Просте додавання +до змінної рядка призведе до (float) і видалить нулі:

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

Для всіх, хто заходить на цей веб-сайт із тією ж проблемою, що і комута, замініть:

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

до:

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


Якщо потрібно видалити дві нулі , то змініть на:

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

Детальніше тут: Номер PHP: десяткова крапка видно лише за потреби


10

Якщо ви хочете видалити нульові цифри безпосередньо перед відображенням на сторінці чи шаблоні.

Ви можете використовувати Sprintf () функцію

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

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

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

Дякую, я любив цю відповідь. Це дуже корисно для мене.
Суміт Кумар Гупта

9

Ви повинні кидати свої цифри як плавці, що зробить це за вас.

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

Результатом цього стане те, що ви шукаєте.

42.422005


1
Поплавкове лиття також може пошкодити ваш номер. наприклад (float)'0.1234567890124567890123456789'стає 0.12345678901246.
1616 року

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

Немає нічого, що неможливо виправити простим регулярним виразом;)

http://xkcd.com/208/


1
Знімає значні 0s, такі як в "100". Також не вдається зняти 0звідти "100.010".
1616

2
Усі відступайте! $x = preg_replace("/(\.0*$)|((?<=\.\d*)0+$)/",'',$x);
Емануель С.


2

Завдяки цьому питання старе. По-перше, мені шкода цього.

Питання стосується числа xxx.xx, але у випадку, якщо це x, xxx.xxxxx або різниця десяткових роздільників, таких як xxxx, xxxx, це може бути важче знайти та вилучити нульові цифри з десяткового значення.

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

І ось код для тесту.

$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.

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

Результат цього - 1.

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

echo floatval('1000.00');
//1000

Ви відповідаєте на запитання з 2013 року
В.Тодоров,


1

Дивно, коли я виймаю номер із бази даних типу "float" і якщо мій номер є колишнім. 10000, коли я плаваю, це стає 1.

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

Я перевірив всі рішення, наведені вище, але не працював.


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

0

Складний спосіб, але працює:

$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

Наведені вище рішення є оптимальним способом, але у випадку, якщо ви хочете мати своє, ви можете використати це. Що робить цей алгоритм, він починається в кінці рядка і перевіряє, чи є його 0 , якщо він встановлює порожній рядок, а потім переходить до наступного символу ззаду до останнього символу > 0



0

Це моє невелике рішення ... Можна включити до класу та встановити вар

приватний $ dsepparator = '.'; // десяткові особи приватного $ tsepparator = ','; // тис

Це можна встановити конструктором і змінити на користувачу 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

0

Це моє рішення. Я хочу зберегти можливість додавання роздільника тисяч

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

0

Це проста функція з одним рядком за допомогою rtrim, збереження роздільника і десяткової крапки:

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

0

Я знайшов це рішення найкращим:

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

Просто і точно!

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

0

Кінцеве рішення: Єдиний безпечний спосіб - використовувати регулярний вираз:

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

він буде працювати в будь-якому випадку



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

1
Це покращило б якість вашої відповіді, якби ви надали пояснення того, що робить ваш код і як він вирішить оригінальне питання.
Найджел Рен

@Nikhil Gyan Я згоден, що ця відповідь не велика. Не соромтесь відмовитися. Однак я, принаймні, не думаю, що це досить погано для прапора дуже низької якості
Сем Хартман,

-2

Цей код видалить нуль після точки і поверне лише дві десяткові цифри.

$ номер = 1200,0000;
str_replace ('. 00', '', number_format ($ number, 2, '.', ''));

Вихід буде: 1200

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.