web-dev-qa-db-ja.com

PHP小数点以下2桁に切り捨てるには?

PHPの小数点以下2桁に切り捨てる必要があります。

49.955

になる...

49.95

number_formatを試しましたが、これは値を49.96に丸めるだけです。 substrを使用することはできません。これは、数値が小さい場合があるためです(7.950など)。これまでのところ、これに対する答えを見つけることができませんでした。

助けていただければ幸いです。

41
Adam Moss

これは機能します:floor($number * 100) / 100

75
GeoffreyB

文字列関数を使用せずにトリックを実行するNice関数を次に示します。

<?php
function floorp($val, $precision)
{
    $mult = pow(10, $precision); // Can be cached in lookup table        
    return floor($val * $mult) / $mult;
}

print floorp(49.955, 2);
?>

他のオプションは、丸める前に分数を減算することです:

function floorp($val, $precision)
{
    $half = 0.5 / pow(10, $precision); // Can be cached in a lookup table
    return round($val - $half, $precision);
}
23
huysentruitw

残念ながら、以前の回答(受け入れられたものを含む)は、可能なすべての入力に対して機能しません。

1)sprintf('%1.'.$precision.'f', $val)

2の精度で失敗します。14.239は14.23を返します(ただし、この場合は14.24を返します)。

2)floatval(substr($val, 0, strpos($val, '.') + $precision + 1))

精度0で失敗します。14は14を返します(ただし、この場合は1を返します)

3)substr($val, 0, strrpos($val, '.', 0) + (1 + $precision))

精度0で失敗します:-1は-1を返します(ただし、この場合は '-'を返します)

4)floor($val * pow(10, $precision)) / pow(10, $precision)

私はこれを広範囲に使用しましたが、最近、その欠陥を発見しました。一部の値でも失敗します。 2の精度で:2.05は2.05を返します(ただし、この場合は2.04を返します!!)

これまでのところ、すべてのテストに合格する唯一の方法は、残念ながら文字列操作を使用することです。 rationalbossに基づく私のソリューションは、次のとおりです。

function floorDec($val, $precision = 2) {
    if ($precision < 0) { $precision = 0; }
    $numPointPosition = intval(strpos($val, '.'));
    if ($numPointPosition === 0) { //$val is an integer
        return $val;
    }
    return floatval(substr($val, 0, $numPointPosition + $precision + 1));
}

この関数は、正と負の数、および必要な精度で機能します。

18
Alex

入力を100倍し、floor()してから、結果を100で除算します。

6
GordonM

round() 関数を試してください

このような:round($num, 2, PHP_ROUND_HALF_DOWN);

4
user1606963
function roundDown($decimal, $precision)
{
    $sign = $decimal > 0 ? 1 : -1;
    $base = pow(10, $precision);
    return floor(abs($decimal) * $base) / $base * $sign;
}

// Examples
roundDown(49.955, 2);           // output: 49.95
roundDown(-3.14159, 4);         // output: -3.1415
roundDown(1000.000000019, 8);   // output: 1000.00000001

この関数は、任意の精度の正および負の小数で動作します。

コード例: http://codepad.org/1jzXjE5L

2
Sterling Beason
function floorToPrecision($val, $precision = 2) {
        return floor(round($val * pow(10, $precision), $precision)) / pow(10, $precision);
    }
1
Yatish Balaji

Bcdiv PHP関数。

bcdiv(49.955, 1, 2)
1
Sanaullah Ahmad

これを達成するための非常に簡単な方法があると思います:

$rounded = bcdiv($val, 1, $precision);

実施例 です。 BCMathをインストールする必要がありますが、通常はPHPインストール。:) ドキュメントはこちら にバンドルされていると思います。

1
Jamie Robinson

次を使用できます。

$num = 49.9555;
echo substr($num, 0, strpos($num, '.') + 3);
0
rationalboss

最後の部分が5以下の場合にのみ小数を切り捨てる場合、最良の解決策は以下を使用することです。

round(4.955,2,PHP_ROUND_HALF_DOWN);

ここで、常に小数を切り捨てて、小数の量を制御したい場合、最善の解決策は次のとおりです。

round(floor(4.957*100)/100,2)

また、「100」の数値は「2」の10進数に合わせてスケーリングする必要があることも考慮してください。例えば。小数点以下4桁が必要な場合は、10000で乗算し、10000で除算する必要があります。そのため、そのポイントを超えると数字が失われます。

0

すべての正または負の数、整数または小数で動作する正規表現を使用した代替ソリューション:

if (preg_match('/^-?(\d+\.?\d{1,2})\d*$/', $originalValue, $matches)){
    $roundedValue = $matches[1];
} else {
    throw new \Exception('Cannot round down properly '.$originalValue.' to two decimal places');
}
0
Luke Cousins

@huysentruitwと@Alexの回答に基づいて、私はトリックを行う必要がある次の関数を思い付きました。

アレックスの答えで与えられたすべてのテストに合格し(これが不可能な理由として)、huysentruitwの答えに基づいて構築されます。

function trim_number($number, $decimalPlaces) {
    $delta = (0 <=> $number) * (0.5 / pow(10, $decimalPlaces));
    $result = round($number + $delta, $decimalPlaces);
    return $result ?: 0; // get rid of negative zero
}

重要なのは、元の番号記号に基づいてデルタを加算または減算し、負の数のトリミングもサポートすることです。最後のことは、負のゼロ(-0)を取り除くことです。これは望ましくない動作になる可能性があるためです。

「テスト」プレイグラウンドへのリンク

編集:bcdivは行く方法のようです。

// round afterwards to cast 0.00 to 0
// set $divider to 1 when no division is required
round(bcdiv($number, $divider, $decimalPlaces), $decimalPlaces);
0
sidon

フォーマットされた出力を使用する

sprintf("%1.2f",49.955) //49.95

[〜#〜] demo [〜#〜]

0