切り上げずに小数を切り捨てたい。たとえば、1.505がある場合、最後の10進数をドロップしたいので、値は1.50になります。 PHPにそのような関数はありますか?
この方法で floor() が必要です:
$rounded = floor($float*100)/100;
または、整数にキャストします:
$rounded = 0.01 * (int)($float*100);
この方法では、切り上げられません。
$float = 1.505;
echo sprintf("%.2f", $float);
//outputs 1.50
遅すぎるかもしれませんが、良い方法は次のとおりです。
$getTruncatedValue = function( $value, $precision )
{
//Casts provided value
$value = ( string )$value;
//Gets pattern matches
preg_match( "/(-+)?\d+(\.\d{1,".$precision."})?/" , $value, $matches );
//Returns the full pattern match
return $matches[0];
};
var_dump
(
$getTruncatedValue(1.123,1), //string(3) "1.1"
$getTruncatedValue(1.345,2), //string(4) "1.34"
$getTruncatedValue(1.678,3), //string(5) "1.678"
$getTruncatedValue(1.90123,4) //string(6) "1.9012"
);
注:小数を切り捨てるネイティブなアプローチを見つけるのは非常に難しく、sprintfやその他の文字列関連の関数を使用して実行することは不可能だと思います。
これを+ veと-ve番号の両方で正確に行うには、以下を使用します。
-+ ve番号用のphp floor()
関数
--ve番号用のphp ceil()
関数
_function truncate_float($number, $decimals) {
$power = pow(10, $decimals);
if($number > 0){
return floor($number * $power) / $power;
} else {
return ceil($number * $power) / $power;
}
}
_
この理由は、floor()
は常に数値を丸めるdownではなくゼロに向かって。
ie floor()
は、-ve数をより大きな絶対値に効果的に丸めます
eg floor(1.5) = 1
while floor(-1.5) = -2
したがって、_multiply by power, remove decimals, divide by power
_ truncateメソッドの場合:
-floor()
は正数に対してのみ機能します
-ceil()
は負の数でのみ機能します
これをテストするには、次のコードを http://phpfiddle.org/lite (または同様の)のエディターにコピーします。
_<div>Php Truncate Function</div>
<br>
<?php
function truncate_float($number, $places) {
$power = pow(10, $places);
if($number > 0){
return floor($number * $power) / $power;
} else {
return ceil($number * $power) / $power;
}
}
// demo
$lat = 52.4884;
$lng = -1.88651;
$lat_tr = truncate_float($lat, 3);
$lng_tr = truncate_float($lng, 3);
echo 'lat = ' . $lat . '<br>';
echo 'lat truncated = ' . $lat_tr . '<br>';
echo 'lat = ' . $lng . '<br>';
echo 'lat truncated = ' . $lng_tr . '<br><br>';
// demo of floor() on negatives
echo 'floor (1.5) = ' . floor(1.5) . '<br>';
echo 'floor (-1.5) = ' . floor(-1.5) . '<br>';
?>
_
$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;
これにより、フロート値を丸めずに短縮できます。
_1.505
_をStringデータ型に変換し、substring()
を使用して最後の文字を切り捨てることができます。
そして再びinteger
に変換します。
RenaPot、IsisCode、goredwardsの答えは正しくありません。
コンピュータでのフロートの動作(一般的に)のため、フロートは正確ではありません。
問題を再現するには:
_floor(19.99 * 100); // Outputs 1998 instead of 1999
floor( 5.10 * 100); // Outputs 509 instead of 510
_
PHP内部では、_19.99 * 100
_は_1998.999999999999999
_のようなものになり、そのfloor
を実行すると_1998
_を取得します。
解決策:
解決策1:使用するbcmathライブラリ(@SamyMassoudで推奨)をインストールしている場合(共有ホスティングサーバーによっては、デフォルトでインストールされていない場合があります)。そのようです:
_//floor(19.99 * 100);// Original
floor(bcmul(19.99, 100));// Outputs 1999
_
解決策2:文字列操作(私の推奨):
_// Works with positive and negative numbers, and integers and floats and strings
function withoutRounding($number, $total_decimals) {
$number = (string)$number;
if($number === '') {
$number = '0';
}
if(strpos($number, '.') === false) {
$number .= '.';
}
$number_arr = explode('.', $number);
$decimals = substr($number_arr[1], 0, $total_decimals);
if($decimals === false) {
$decimals = '0';
}
$return = '';
if($total_decimals == 0) {
$return = $number_arr[0];
} else {
if(strlen($decimals) < $total_decimals) {
$decimals = str_pad($decimals, $total_decimals, '0', STR_PAD_RIGHT);
}
$return = $number_arr[0] . '.' . $decimals;
}
return $return;
}
// How to use:
withoutRounding(19.99, 2);// Return "19.99"
withoutRounding(1.505, 2);// Return "1.50"
withoutRounding(5.1, 2);// Return "5.10"
_
私はこれが遅い答えであることを知っていますが、ここに簡単な解決策があります。 1.505のOPの例を使用すると、次を使用して1.50に到達できます。
function truncateExtraDecimals($val, $precision) {
$pow = pow(10, $precision);
$precise = (int)($val * $pow);
return (float)($precise / $pow);
}
これにより、どの関数を使用するかをフィルタリングすることなく正と負の値を管理し、他の関数がその値をどう処理するか心配することなく結果を修正できます。
$val = 1.509;
$truncated = sprintf('%.2f', truncateExtraDecimals($val, 2));
echo "Result: {$truncated}";
Result: 1.50
表示するには、正確に2桁の小数を取得するにはsprintfが必要です。そうでない場合、結果は1.50ではなく1.5になります。
利用可能な場合、bc関数を使用できます。
echo bcadd(sprintf('%F', 5.445), '0', 2); // => 5.44
echo sprintf('%.2F', 5.445); // => 5.45