Xóa các chữ số 0 vô dụng khỏi số thập phân trong PHP


163

Tôi đang cố gắng tìm một cách nhanh chóng để xóa zero decimalskhỏi các giá trị số như thế này:

echo cleanNumber('125.00');
// 125

echo cleanNumber('966.70');
// 966.7

echo cleanNumber(844.011);
// 844.011

Có tồn tại một số cách tối ưu để làm điều đó?


4
Vì các giá trị của bạn thực sự là các chuỗi, tại sao không sử dụng rtrim () - php.net/manual/en/feft.rtrim.php - với '0.' là đối số thứ hai
Mark Baker

Xin lỗi, tôi đã không hoàn toàn rõ ràng, chúng không phải lúc nào cũng là chuỗi, tôi sửa câu hỏi.
vitto

9
@Mark Baker: đó là một cách tiếp cận tồi vì số 120 sẽ bị cắt giảm thành 12
machineaddict

@machineaddict - điều đó sẽ xảy ra nếu và chỉ khi các giá trị chuỗi không có dấu thập phân ..... tất cả những giá trị được trích dẫn bởi OP đều có dấu thập phân.
Đánh dấu Baker

2
Sau đó, bạn nên thêm một thông báo táo bạo trong câu trả lời của bạn, rằng nó chỉ hoạt động nếu có số thập phân.
máy móc

Câu trả lời:


353

$num + 0 không lừa

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

Trong nội bộ, điều này tương đương với việc đúc để nổi với (float)$numhoặc floatval($num)nhưng tôi thấy nó đơn giản hơn.


45
Tôi nghĩ rằng đây là một mánh khóe bẩn thỉu. Tôi không thích nó bởi vì mã không nói về hành vi của anh ta như floatval()đang làm điều đó.
ESCOBAR

4
floatvalHành vi của @ESCOBAR đang trở lại nổi. Tôi sẽ tranh luận sử dụng nó như một định dạng số thập phân cũng không rõ ràng hoặc rõ ràng.
lafor

2
Đây là một điều rất không rõ ràng. Nhóm của chúng tôi vừa gặp phải điều này trong mã của chúng tôi và nó đã khiến 3 nhà phát triển bối rối trong một thời gian. Tôi nghĩ câu trả lời của Mark là một sự thay thế tốt hơn. Nó dài hơn, nhưng ý định của nó là rõ ràng.
jfbalanc

2
@jfbalanc//COMMENT
Webinan

1
@ESCOBAR Không thực sự, đó là một phương pháp được đề xuất chính thức để đánh máy ... tìm kiếm "kiểu tung hứng" trên php.net
Gergely Lukacsy

101

bạn chỉ có thể sử dụng floatvalchức năng

echo floatval('125.00');
// 125

echo floatval('966.70');
// 966.7

echo floatval('844.011');
// 844.011

2
nó không thành công khi dấu phân cách nghìn là dấu chấm và dấu thập phân là dấu phẩy.
Munna Khan

20

Đây là những gì tôi sử dụng:

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

NB Giả định .này là dấu phân cách thập phân. Nó có lợi thế là nó sẽ hoạt động trên các số lớn (hoặc nhỏ) tùy ý vì không có phôi nổi. Nó cũng sẽ không biến số thành ký hiệu khoa học (ví dụ 1.0E-17).


Đây không phải là một giải pháp an toàn, nếu giá không phải là số thập phân thì sao, ví dụ nếu nhà phát triển nhân giá với một số nguyên thì chúng ta có một số nguyên
amin

@alex Hàm này hoạt động trên các số nguyên, số float và chuỗi.
mở

1
Giải pháp hoàn hảo như người trợ giúp cho bcmath
Kart Av1k

17

Chỉ cần thêm +vào biến chuỗi của bạn sẽ khiến typecast (float) và loại bỏ các số không:

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

Thay vào đó, đối với mọi người đến trang web này có cùng một vấn đề với dấu phẩy, hãy thay đổi:

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

đến:

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


Nếu có hai số không bị xóa, sau đó đổi thành:

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

Xem thêm tại đây: Số PHP: dấu thập phân chỉ hiển thị nếu cần


10

Nếu bạn muốn xóa các chữ số 0 ngay trước đó để hiển thị trên trang hoặc mẫu.

Bạn có thể sử dụng sprintf) ( chức năng

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

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

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

Cảm ơn tôi yêu câu trả lời này. Điều này rất hữu ích cho tôi.
Sumit Kumar Gupta

9

Bạn nên bỏ số của bạn dưới dạng số float, sẽ làm điều này cho bạn.

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

Đầu ra của điều này sẽ là những gì bạn đang tìm kiếm.

42.422005


1
Phao đúc cũng có thể làm hỏng số của bạn. ví dụ (float)'0.1234567890124567890123456789'trở thành 0.12345678901246.
mở

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

Không có gì không thể sửa được bằng một biểu thức đơn giản;)

http://xkcd.com/208/


1
Loại bỏ 0các s đáng kể như trong "100". Cũng không thoát 0khỏi s "100.010".
mở

2
Mọi người hãy đứng lại! $x = preg_replace("/(\.0*$)|((?<=\.\d*)0+$)/",'',$x);
Emanuel S.

5

Kiểu chữ đến a float.

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

2

Do câu hỏi này là cũ. Đầu tiên, tôi xin lỗi về điều này.

Câu hỏi là về số xxx.xx nhưng trong trường hợp đó là x, xxx.xxxxx hoặc dấu tách thập phân khác nhau như xxxx, xxxx, điều này có thể khó tìm và loại bỏ các chữ số 0 khỏi giá trị thập phân.

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

Và đây là mã để thử nghiệm.

$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

Hãy cẩn thận với việc thêm +0.

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

Kết quả của việc này là 1.

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

echo floatval('1000.00');
//1000

Bạn đang trả lời một câu hỏi từ năm 2013.
VTodorov

3
Nó không phải là một vấn đề để trả lời một câu hỏi cũ, nếu nó có thể giúp người đọc thực tế
Rjust85

1

Thật kỳ lạ, khi tôi lấy một số ra khỏi cơ sở dữ liệu với kiểu "float" và nếu số của tôi là ex. 10000 khi tôi thả trôi nó, nó trở thành 1.

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

Tôi đã thử nghiệm tất cả các giải pháp trên nhưng không hiệu quả.


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

0

Cách phức tạp nhưng hoạt động:

$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

các giải pháp trên là cách tối ưu nhưng trong trường hợp bạn muốn có riêng mình, bạn có thể sử dụng giải pháp này. Thuật toán này bắt đầu ở cuối chuỗi và kiểm tra xem nó có phải là 0 không , nếu nó được đặt thành chuỗi rỗng và sau đó chuyển đến ký tự tiếp theo cho đến khi ký tự cuối cùng là > 0



0

Đó là giải pháp nhỏ của tôi ... Có thể bao gồm một lớp và đặt bình

riêng tư $ dsepparator = '.'; // số thập phân riêng $ tsepparator = ','; // nghìn

Điều đó có thể được thiết lập bởi constructor và thay đổi thành người dùng 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
     */

}

Vì vậy, tôi đã xây dựng một lớp mẫu với ít mẫu. Tốt hơn? =)
Paykoman

0

Đây là giải pháp của tôi. Tôi muốn giữ khả năng thêm hàng ngàn dấu phân cách

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

0

Đây là một hàm một dòng đơn giản sử dụng rtrim, lưu dấu phân cách và dấu thập phân:

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

0

Tôi thấy giải pháp này là tốt nhất:

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

Đơn giản và chính xác!

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

0

Giải pháp cuối cùng: Cách an toàn duy nhất là sử dụng regex:

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

nó sẽ làm việc cho mọi trường hợp


0

Sau đây là đơn giản hơn nhiều

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

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

1
Nó sẽ cải thiện chất lượng câu trả lời của bạn nếu bạn cung cấp giải thích về mã của bạn làm gì và cách giải quyết câu hỏi ban đầu.
Nigel Ren

@Nikhil Gyan Tôi đồng ý câu trả lời này không hay. Hãy thoải mái để xuống. Tuy nhiên, ít nhất tôi không nghĩ rằng nó đủ tệ cho cờ chất lượng rất thấp
Sam Hartman

-2

Mã này sẽ loại bỏ số 0 sau điểm và sẽ chỉ trả về hai chữ số thập phân.

$ số = 1200.0000;
str numplace ('. 00', '', number_format ($ number, 2, '.', ''));

Đầu ra sẽ là: 1200

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.