PHPの小数点以下を小数点以下2桁に切り捨てて、次のようにする必要があります。
49.955
になります...
49.95
number_formatを試しましたが、これは値を49.96に丸めるだけです。数値が小さい可能性があるため(7.950など)、substrを使用できません。私はこれまでこれに対する答えを見つけることができませんでした。
どんな助けでも大歓迎です。
PHPの小数点以下を小数点以下2桁に切り捨てて、次のようにする必要があります。
49.955
になります...
49.95
number_formatを試しましたが、これは値を49.96に丸めるだけです。数値が小さい可能性があるため(7.950など)、substrを使用できません。私はこれまでこれに対する答えを見つけることができませんでした。
どんな助けでも大歓迎です。
これは機能します:floor($number * 100) / 100
残念ながら、以前の回答(受け入れられたものを含む)のいずれも、すべての可能な入力に対して機能しません。
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の1つに基づく私の解決策は、次のとおりです。
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));
}
この関数は、正の数と負の数、および必要な精度で機能します。
これは、文字列関数を使用せずにトリックを実行する優れた関数です。
<?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);
?>
もう1つのオプションは、丸める前に小数部を減算することです。
function floorp($val, $precision)
{
$half = 0.5 / pow(10, $precision); // Can be cached in a lookup table
return round($val - $half, $precision);
}
これを達成するための非常に簡単な方法があると思います。
$rounded = bcdiv($val, 1, $precision);
これが実際の例です。BCMathをインストールする必要がありますが、通常はPHPインストールにバンドルされていると思います。:)ここにドキュメントがあります。
入力に100を掛け、floor()してから、結果を100で割ります。
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
bcdivPHP関数を使用できます。
bcdiv(49.955, 1, 2)
round()
機能を試す
このような:round($num, 2, PHP_ROUND_HALF_DOWN);
困っている人のために、私は数学関数の誤動作を克服するためにちょっとしたトリックを使用しました。たとえば、floorやintval(9.7 * 100)=969奇妙なものです。
function floor_at_decimals($amount, $precision = 2)
{
$precise = pow(10, $precision);
return floor(($amount * $precise) + 0.1) / $precise;
}
したがって、少量を追加すると(とにかくフロアになります)、何らかの形で問題が修正されます。
function floorToPrecision($val, $precision = 2) {
return floor(round($val * pow(10, $precision), $precision)) / pow(10, $precision);
}
次を使用できます。
$num = 49.9555;
echo substr($num, 0, strpos($num, '.') + 3);
すべての正または負の数、整数または小数で機能する正規表現を使用する代替ソリューション:
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');
}
@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);
sprintf("%1.2f",49.955) //49.95
四捨五入せずに小数を切り捨てる必要がある場合-これは適切ではありません。これは、最後に49.95 5まで正しく機能するためです。たとえば、49.95 7の場合は、49.96
に四捨五入されます。最も普遍的です。
やってみましたround($val,2)
か?
round()
関数に関する詳細情報