web-dev-qa-db-ja.com

値を丸めずに、小数点以下2桁を削除します

私はそのようなPHP変数に値を持っています

_$var='2.500000550';
echo $var
_

私が欲しいのは、2桁の後にすべての小数点を削除することです。

今のように変数の値は

_$var='2.50';
echo $var
_

この値はmysql databseからのものであることに注意してください

しかし、_round php function_を使用すると、丸められましたが、丸める必要はありません。小数点以下2桁の単純な数字をすべて削除する必要があります。

私は疲れて、flot()と他の多くのオプションは成功しませんでした。

ありがとう

41
air

TL; DR:

PHPネイティブ関数 bcdiv は、必要なことを正確かつ適切に行うようです。

単純に数値を「切り捨てる」には、bcdiv($var, 1, 2);で、2は保持する小数の数です(1は分母です-数値を1で割ると、元の数値を必要な小数点以下に切り捨てることができます)。

完全な回答(履歴用)

これは、考えられるよりもわかりにくいことがわかります。

この答えが(誤って)かなり賛成された後、sprintfでさえ丸められることに気付きました。

この答えを削除するのではなく、提案された各ソリューションのより堅牢な説明/議論に変えています。

number_format-正しくありません。 (ラウンド)
数値形式 を使用してみてください:

$var = number_format($var, 2, '.', '');  // Last two parameters are optional
echo $var;
// Outputs 2.50

数値にしたい場合は、フロートに型キャストするだけです:

$var = (float)number_format($var, 2, '.', '');

注:コメントで指摘されているように、これは実際にはround番号です。

sprintf-正しくありません。 (sprintfも丸めます)
数値を丸めないことが重要な場合は、以下の回答に従って、 sprintf を使用します。

$var = sprintf("%01.2f", $var);

floor-まったく違います! (床は負の数を丸めます)

floor 、いくつかの数学で、あなたがやりたいことに近づきます:

floor(2.56789 * 100) / 100; // 2.56

ここで、100は必要な精度を表します。 3桁にしたい場合:

floor(2.56789 * 1000) / 1000; // 2.567

ただし、これには負の数の問題があります。負の数は切り捨てられるのではなく、引き続き丸められます:

floor(-2.56789 * 100) / 100; // -2.57

「古い」正解:床を利用する機能

したがって、完全に堅牢なソリューションには次の機能が必要です。

function truncate_number( $number, $precision = 2) {
    // Zero causes issues, and no need to truncate
    if ( 0 == (int)$number ) {
        return $number;
    }
    // Are we negative?
    $negative = $number / abs($number);
    // Cast the number to a positive to solve rounding
    $number = abs($number);
    // Calculate precision number for dividing / multiplying
    $precision = pow(10, $precision);
    // Run the math, re-applying the negative value to ensure returns correctly negative / positive
    return floor( $number * $precision ) / $precision * $negative;
}

上記の関数の結果:

echo truncate_number(2.56789, 1); // 2.5
echo truncate_number(2.56789);    // 2.56
echo truncate_number(2.56789, 3); // 2.567

echo truncate_number(-2.56789, 1); // -2.5
echo truncate_number(-2.56789);    // -2.56
echo truncate_number(-2.56789, 3); // -2.567

新しい正解

PHPネイティブ関数 bcdiv

echo bcdiv(2.56789, 1, 1);  // 2.5
echo bcdiv(2.56789, 1, 2);  // 2.56
echo bcdiv(2.56789, 1, 3);  // 2.567
echo bcdiv(-2.56789, 1, 1); // -2.5
echo bcdiv(-2.56789, 1, 2); // -2.56
echo bcdiv(-2.56789, 1, 3); // -2.567
98
cale_b
floor(2.500000550 * 100) / 100;

これはあなたの仕事をするはずです...

9
Sujit Agarwal

"2.50"ではなく2.5を返す関数を要求しているので、ここでは算術については話していませんが、しかし- 文字列操作preg_replaceはあなたの友達です:

$truncatedVar = preg_replace('/\.(\d{2}).*/', '.$1', $var);

// "2.500000050" -> "2.50", "2.509" -> "2.50", "-2.509" -> "2.50", "2.5" -> "2.5"

算術を使用する場合は、次を使用します。

$truncatedVar = round($var * 100) / 100);

// "2.500000050" -> "2.5", "2.599" -> "2.59", "-2.599" -> "2.59"
6
flu

number_format で試してください:

echo number_format('2.50000050', 2); // 2.50
5
matino

number_formatは数値を丸めます

php > echo number_format(128.20512820513, 2)."\n";
128.21

Preg_replaceを使用して文字列を実際にカットしました

php > echo preg_replace('/(\.\d\d).*/', '$1', 128.20512820513)."\n";
128.20
3
Liphtier

sprintf を使用します

sprintf("%01.2f", $var);
3
Aurimas Ličkus

PHPネイティブ関数 bcdiv を使用します。

例:

echo bcdiv(3.22871, 1, 1);  // 3.2
echo bcdiv(3.22871, 1, 2);  // 3.22
echo bcdiv(3.22871, 1, 3);  // 3.228
echo bcdiv(-3.22871, 1, 1); // -3.2
echo bcdiv(-3.22871, 1, 2); // -3.22

あなたの場合:

$var='2.500000550';
echo $var
echo bcdiv($var, 1, 2);  // 2.50
2
Faisal

誰かがここに投稿しました

floor(2.500000550 * 100)/ 100;

function cutAfterDot($number, $afterDot = 2){
$a = $number * pow(10, $afterDot);
$b = floor($a);
$c = pow(10, $afterDot);
echo "a $a, b $b, c $c<br/>";
return $b/$c ;
}
echo cutAfterDot(2.05,2);

a 205, b 204, c 100
2.04

そのまま使用しないでください...しかし、イプシロンを少し追加すると...

function cutAfterDot($number, $afterDot = 2){
        return floor($number * pow(10, $afterDot) + 0.00001) / pow(10, $afterDot);
    }

できます!

2

数値を丸めたくないが小数点以下の桁を削除したい場合は、「substr」メソッドを使用できます

substr(string, start, length);
substr(4.96, 0, -1);
0
Fahad Ahmed

床-かなりではありません! (床は負の数を丸めます)

cale_b answerからの可能な解決策。

static public function rateFloor($rate, $decimals)
{

    $div = "1" . str_repeat("0", $decimals);

    if ($rate > 0) {
        return floor($rate * $div) / $div;
    }

    $return = floor(abs($rate) * $div) / $div;

    return -($return);

}

static public function rateCeil($rate, $decimals)
{

    $div = "1" . str_repeat("0", $decimals);

    if ($rate > 0) {
        return ceil($rate * $div) / $div;
    }

    $return = ceil(abs($rate) * $div) / $div;

    return -($return);

}

ポジティブ

レート:0.00302471

床:0.00302400

Ceil:0.00302500

レート:-0.00302471

床:-0.00302400

Ceil:-0.00302500

0
Jon C.

Number_formatは丸めを実行するため、number_formatを使用するソリューションはすべて間違っています。

以下の関数はすべての数値で機能するはずです。「、」を使用する国には小数点記号を指定できます。

function truncate_decimal($number, $truncate_decimal_length = 2, $decimal_character = '.', $thousands_character = '') {

$number = explode($decimal_character, $number);
$number[1] = substr($number[1], 0, $truncate_decimal_length);
$number_truncated = implode($decimal_character, $number);
return number_format($number_truncated, $truncate_decimal_length, $decimal_character, $thousands_character);

}
0
leexonline

従うべき単純な関数は、「0フロアより大きい場合、またはceil」であり、乗算器を使用して、それを実行しながら一時的に小数点より上に上げます。

function trim_num($num_in, $dec_places = 2) {
    $multiplier = pow(10, $dec_places); // 10, 100, 1000, etc
    if ($num_in > 0) {
        $num_out = floor($num_in * $multiplier) / $multiplier;
    } else {
        $num_out = ceil($num_in * $multiplier) / $multiplier;
    }
    return $num_out;
}
0
David Bell

以下は(私が信じていること-そうでない場合は私を修正してください)堅牢な数学的な*ソリューションであり、主にいくつかの他の回答者からの情報に基づいて、私から少し

(* Liphtier's regex-based answer に問題があることを示唆するものではありません-間違いなく、数学的問題であるために正規表現を避けたいと思っている純粋主義者を見ることができます。)

  • sprintf()number_format()(およびround()、明らかに)はすべて丸め操作を実行しているため、質問で要求された非丸め切り捨てには適切ではありません(独自ではありません) 、 少なくとも)。
  • すぐに使える機能の代わりに、一見最もエレガントなソリューションは Sujit Agarwal's answer
  • しかし、フロートの保存方法のため、イプシロンを使用する必要があります- David Constantine's answer (ここで、彼はpow()を使用して以前のソリューションをより一般的にします)指定された精度に基づく適切な要因)。
  • しかし、 cale_b's answer で指摘されているように、floor()(またはおそらくceil())を使用すると、abs()
  • そして、私が追加しようとしている値は次のとおりです。
    • abs()で除算を使用して否定係数を取得する場合、入力が0の場合の特殊なケースを考慮する必要があります。
    • イプシロンを動的に作成する必要があります。静的にハードコードされたイプシロンは、必要な精度に応じて、小さすぎるか大きすぎる場合があります。他の回答でこの問題が解決されているのを見たことはありません。

私が使用しているコードは次のとおりです。

public static function truncate_decimal($number, $leavePlaces = 2)
{
    if ($number == 0) return 0;
    $negate = $number / abs($number);
    $shiftFactor = pow(10, $leavePlaces);
    $epsilon = pow(10, -1 * $leavePlaces);
    return floor(abs($number) * $shiftFactor + $epsilon) / $shiftFactor * $negate;
}
0
Sepster
$num = 118.74999669307;
$cut = substr($num, 0, ((strpos($num, '.')+1)+2));
// Cut the string from first character to a length of 2 past the decimal.
// substr(cut what, start, ( (find position of decimal)+decimal itself)+spaces after decimal) )
echo $cut; 
0
Sujjad Ali