我想去掉小数并且不四舍五入。比如说,如果我有1.505,我想要去掉最后一位小数,使得值变成1.50。PHP中是否有这样一个函数?
你需要这样使用floor():
$rounded = floor($float*100)/100;
或者您可以将其转换为整数:
$rounded = 0.01 * (int)($float*100);
这样它就不会四舍五入了。
使用PHP原生函数bcdiv
echo bcdiv(2.56789, 1, 2); // 2.56
bcdiv()
does require the https://www.php.net/manual/en/book.bc.php PHP extension. Most PHP versions have it enabled by default. To check if your PHP has it enabled, look for "BCMath support => enabled" in the output of phpinfo()
or $ php -i | grep BCMath
- John Kary要准确地进行正数和负数的运算,您需要使用以下函数:
- 对于正数,请使用php的floor()
函数
- 对于负数,请使用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()
总是将数字向下舍入,而不是向零舍入。floor()
有效地将负数向更大的绝对值舍入。floor(1.5) = 1
,而floor(-1.5) = -2
。乘以幂次方、去除小数点、再除以幂次方截取
方法时:floor()
仅适用于正数ceil()
仅适用于负数<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>';
?>
$float = 1.505;
echo sprintf("%.2f", $float);
//outputs 1.50
(float) $float
结合使用效果非常好。 - Jamie Dextersprintf
认为需要进行舍入,则会对浮点数进行四舍五入。例如,对于除法 31 / 53 = 0.584905[...]
,如果我们想要保留三位小数,我们可以使用 sprintf("%.3f", (31 / 53))
,但这并不会返回 0.584,它会返回 0.585。 - Jamie Dexterecho sprintf()
是一种“反模式”。没有任何理由让任何人在任何代码中编写echo sprintf()
-- 每次都应该使用printf()
。这个答案并没有说谎,它提供了样本输入的期望结果:https://3v4l.org/PQoKW。Jamie也没有错--https://3v4l.org/h37XV,Loenix也是正确的https://3v4l.org/SsNUb。因此,这种技术似乎不可靠。 - mickmackusa $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和其他字符串相关函数无法执行该操作。
由于计算机中(通常情况下)浮点数的工作方式,浮点数是不准确的。
要复制此问题:
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"
如果可用,我们可以使用bc函数:
echo bcadd(sprintf('%F', 5.445), '0', 2); // => 5.44
echo sprintf('%.2F', 5.445); // => 5.45
1.505
转换为字符串数据类型,并使用 substring()
截取最后一个字符。
整数
。$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;
$value = 12.9987876;
$value_exp = explode(".", $value);
$value_new = floatval($value_exp[0].'.'.substr($value_exp[1],0,4));
echo $value_new; // output will 12.9987
floor()
和ceil()
- 请参见此答案。 - goredwardsfloor(5.1*100)/100;
的结果是5.09
,而不是期望的5.10
。您可以尝试使用 5.100 或 4.1,得到相同的错误结果。 - Muhammedfloor(19.99 * 100)
返回1998
而不是1999
。这不应该是正确的答案。 - evilReiko