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 'を使用しないでください。2番目の引数として
Mark Ba​​ker

すみません、完全に明確ではありません。それらは常に文字列ではないので、質問を修正します。
vitto

9
@マークベイカー:数120は12にトリミングされるように悪いアプローチである
machineaddict

@machineaddict-文字列の値に小数点がない場合に限り、OPで引用されているものすべてに小数点があります。
マークベイカー、

2
次に、答えに太字の通知を追加する必要があります。小数がある場合にのみ機能します。
machineaddict 2014

回答:


354

$num + 0 トリックを行います。

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

内部的には、これは(float)$numorで浮動小数点にキャストすることと同じですfloatval($num)が、私はそれがより簡単だと思います。


45
これは汚いトリックだと思います。コードはfloatval()それをしているような彼の行動を知らないので、私はそれを好みません。
ESCOBAR 2014

4
@ESCOBAR floatvalの動作は浮動小数点数を返します。小数フォーマッタとしてそれを使用することも、非常に明白でもクリーンでもないと主張します。
lafor 2014年

2
これは非常に不明確です。私たちのチームはコードでこれに遭遇したばかりで、しばらくの間3人の開発者が困惑していました。マークの答えはより良い選択肢だと思います。長いですが、その意図は明らかです。
jfbalanc 2015

2
@jfbalanc//COMMENT
2015年

1
@ESCOBARそうではない、それは正式に提案された型キャストの方法です... php.netで「type juggling」を検索してください
Gergely Lukacsy

101

あなたはfloatval関数を使うことができます

echo floatval('125.00');
// 125

echo floatval('966.70');
// 966.7

echo floatval('844.011');
// 844.011

2
3桁ごとの区切り記号がドットで、小数点がコンマの場合は失敗します。
ムンナカーン2018

20

これは私が使用するものです:

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

注意これは.小数点区切り文字であると想定しています。floatキャストがないため、任意に大きい(または小さい)数値で機能するという利点があります。また、数値を科学的表記に変換しません(例:1.0E-17)。


これは安全な解決策ではありません。価格が小数でない場合はどうでしょうか。たとえば、開発者が価格に整数を掛けると、整数になります
amin

@alexこの関数は、整数、浮動小数点数、および文字列に対して機能します。
mpen

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


削除する2つのゼロがある場合は、次のように変更します。

$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

ありがとうこの回答を気に入りました。これは私にとって非常に役に立ちます。
Sumit Kumar Gupta

9

あなたはあなたのためにこれを行う浮動小数点数としてあなたの数をキャストするべきです。

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

これの出力は、あなたが探しているものになります。

42.422005


1
フロートキャストも数値を壊す可能性があります。たとえばに(float)'0.1234567890124567890123456789'なり0.12345678901246ます。
mpen 2016年

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

単純な正規表現では修正できないものはありません;)

http://xkcd.com/208/


1
0のような重要なsを取り除きます"100"。また、0sの除去に失敗し"100.010"ます。
mpen 2016年

2
みんなスタンドバック!$x = preg_replace("/(\.0*$)|((?<=\.\d*)0+$)/",'',$x);
Emanuel S.


2

この質問のために古いです。まず、ごめんなさい。

問題は数値xxx.xxについてですが、それがx、xxx.xxxxxまたはxxxx、xxxxなどの差分小数点記号である場合、10進数値からゼロ桁を見つけて削除することは困難です。

/**
 * 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
。– VTodorov '19年

3
それが実際の読者を助けることができるならば、それは古い質問に答えることは問題ではありません
Reign.85

1

奇妙なことですが、データベースから「float」型の数値を取得した場合、および私の数値がexの場合です。floatvalすると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 2017

0

これが私の解決策です。何千ものセパレータを追加する機能を維持したい

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

0

これは、rtrim、保存区切り文字、小数点を使用する単純な1行の関数です。

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
あなたのコードが何をするのか、そしてそれが元の質問をどのように解決するのかについての説明を提供したなら、それはあなたの答えの質を改善するでしょう。
Nigel Ren

@Nikhil Gyan私はこの答えは素晴らしいものではないことに同意します。気軽に書き留めてください。しかし、私はそれが非常に低い品質の旗にとって十分に悪いとは思わない
Sam Hartman

-2

このコードは、ポイントの後にゼロを削除し、2桁の10進数のみを返します。

$ number = 1200.0000;
str_replace( '。00'、 ''、number_format($ number、2、 '。'、 ''));

出力は次のようになります:1200

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.