TL;DR:
PHP 原生函数 bcdiv 似乎准确地完成了所需的工作,而且做得很好。
要简单地“截断”一个数字,bcdiv($var, 1, 2); 其中 2 是要保留的小数位数(1 是分母 - 将数字除以 1 可以简单地将原始数字截断到所需的小数位)
完整答案(历史记录)
事实证明,这比人们想象的更难以捉摸。
在这个答案被(错误地)点赞之后,我注意到即使是 sprintf 也会圆整。
我没有删除这个答案,而是将其转化为对每个提议的解决方案的更强有力的解释/讨论。
number_format - 不正确。 (回合)
尝试使用number format:
$var = number_format($var, 2, '.', ''); // Last two parameters are optional
echo $var;
// Outputs 2.50
如果您希望它是一个数字,那么只需将其类型转换为浮点数:
$var = (float)number_format($var, 2, '.', '');
注意: 正如 cmets 中所指出的,这实际上是对数字进行四舍五入。
sprintf - 不正确。 (sprintf 也是四舍五入)
如果不四舍五入很重要,那么根据下面的答案,使用sprintf:
$var = sprintf("%01.2f", $var);
地板 - 不完全是! (地板舍入负数)
floor,通过一些数学运算,将接近于做你想做的事:
floor(2.56789 * 100) / 100; // 2.56
其中 100 代表您想要的精度。如果你想要三位数,那么:
floor(2.56789 * 1000) / 1000; // 2.567
但是,这对负数有问题。负数仍会四舍五入,而不是截断:
floor(-2.56789 * 100) / 100; // -2.57
“旧”正确答案:利用地板的功能
所以一个完全健壮的解决方案需要一个函数:
function truncate_number( $number, $precision = 2) {
// Zero causes issues, and no need to truncate
if ( 0 == (int)$number ) {
return $number;
}
// Are we negative?
$negative = $number / abs($number);
// Cast the number to a positive to solve rounding
$number = abs($number);
// Calculate precision number for dividing / multiplying
$precision = pow(10, $precision);
// Run the math, re-applying the negative value to ensure returns correctly negative / positive
return floor( $number * $precision ) / $precision * $negative;
}
上述函数的结果:
echo truncate_number(2.56789, 1); // 2.5
echo truncate_number(2.56789); // 2.56
echo truncate_number(2.56789, 3); // 2.567
echo truncate_number(-2.56789, 1); // -2.5
echo truncate_number(-2.56789); // -2.56
echo truncate_number(-2.56789, 3); // -2.567
新的正确答案
使用PHP原生函数bcdiv
echo bcdiv(2.56789, 1, 1); // 2.5
echo bcdiv(2.56789, 1, 2); // 2.56
echo bcdiv(2.56789, 1, 3); // 2.567
echo bcdiv(-2.56789, 1, 1); // -2.5
echo bcdiv(-2.56789, 1, 2); // -2.56
echo bcdiv(-2.56789, 1, 3); // -2.567