不幸的是,之前的答案(包括接受的答案)都不适用于所有可能的输入。
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 one的解决方案是:
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));
}
此函数适用于正数和负数,以及所需的任何精度。