我需要将PHP中的小数舍入到小数点后两位,以便:
49.955
...变为
49.95
我尝试了 number_format ,但这只是将值四舍五入为 49.96 。我不能使用 substr ,因为数字可能更小(例如7.950)。到目前为止,我一直无法找到答案。
任何帮助都非常感激。
答案 0 :(得分:75)
这可以有效:floor($number * 100) / 100
答案 1 :(得分:22)
这是一个不使用字符串函数的好方法:
<?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);
}
答案 2 :(得分:17)
不幸的是,之前的答案(包括已接受的答案)都不适用于所有可能的输入。
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(但在这种情况下返回&#39; - &#39;)
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));
}
此功能适用于正数和负数,以及所需的任何精度。
答案 3 :(得分:6)
将输入乘以100,floor(),然后将结果除以100.
答案 4 :(得分:2)
尝试round()
功能
像这样:round($num, 2, PHP_ROUND_HALF_DOWN);
答案 5 :(得分:2)
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
答案 6 :(得分:1)
我认为有一个很简单的方法可以实现:
$rounded = bcdiv($val, 1, $precision);
这里是working example。您需要安装BCMath,但我认为它通常与PHP安装捆绑在一起。 :)Here is the documentation。
答案 7 :(得分:0)
对于有需要的人,我使用了一些技巧来克服数学函数故障,例如floor或 intval(9.7 * 100)= 969 很奇怪。
function floor_at_decimals($amount, $precision = 2)
{
$precise = pow(10, $precision);
return floor(($amount * $precise) + 0.1) / $precise;
}
因此,添加少量(无论如何都会降低)可以以某种方式解决该问题。
答案 8 :(得分:0)
基于@huysentruitw和@Alex的答案,我想出了以下应该可以解决问题的功能。
它通过了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);
答案 9 :(得分:0)
您可以使用bcdiv PHP函数。
bcdiv(49.955, 1, 2)
答案 10 :(得分:0)
Reference
答案 11 :(得分: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');
}
答案 12 :(得分:0)
您可以使用:
$num = 49.9555;
echo substr($num, 0, strpos($num, '.') + 3);
答案 13 :(得分:0)
答案 14 :(得分:-2)
答案 15 :(得分:-2)
sprintf("%1.2f",49.955) //49.95
如果你需要在没有舍入的情况下截断小数 - 这是不合适的,因为它会在49.95 5 结束时正常工作,如果数字更多,例如49.95 7 它会四舍五入到49.96
对我而言,Lght对地板的回答是最普遍的。
答案 16 :(得分:-4)
你试过round($val,2)
吗?
有关round()
功能