我有一个 PHP 变量中存储了这样的值
$var='2.500000550';
echo $var
我想要的是删除小数点后两位以后的所有数字。
比如现在变量的值为
$var='2.50';
echo $var
请注意这个值是来自MySQL数据库的
但是当我使用round PHP函数
时,我得到了一个四舍五入的结果,但我不需要四舍五入,我只需要保留小数点后两位。
我尝试了float()
和很多其他选项都没有成功。
谢谢。
我有一个 PHP 变量中存储了这样的值
$var='2.500000550';
echo $var
我想要的是删除小数点后两位以后的所有数字。
比如现在变量的值为
$var='2.50';
echo $var
请注意这个值是来自MySQL数据库的
但是当我使用round PHP函数
时,我得到了一个四舍五入的结果,但我不需要四舍五入,我只需要保留小数点后两位。
我尝试了float()
和很多其他选项都没有成功。
谢谢。
使用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, '.', '');
注意:正如在评论中指出的那样,这确实会四舍五入该数字。
sprintf-不正确。(sprintf也会四舍五入)
如果不四舍五入数字很重要,则根据下面的答案使用sprintf:
$var = sprintf("%01.2f", $var);
floor - 并不完全符合要求!(floor会将负数四舍五入)
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
bcdiv
。 - random_user_name=
符号,则会将0
无意中赋值给$number
变量。如果在_我的_代码中忘记了一个=
符号,则会出现错误,PHP将无法运行。 - random_user_namefloor(2.500000550 * 100) / 100;
这应该能够完成你的任务...
您正在请求一个返回"2.50"
而不是2.5
的函数,所以这里不涉及算术运算,而是字符串操作。那么,preg_replace
就是您的好帮手:
$truncatedVar = preg_replace('/\.(\d{2}).*/', '.$1', $var);
// "2.500000050" -> "2.50", "2.509" -> "2.50", "-2.509" -> "2.50", "2.5" -> "2.5"
$truncatedVar = round($var * 100) / 100);
// "2.500000050" -> "2.5", "2.599" -> "2.59", "-2.599" -> "2.59"
'intval(2.092484 * 100) / 100'
是 2.09
,但我认为使用 round
而不是 intval
应该可以使其更加坚固。谢谢! - flupreg_replace('/\.\d{2}\K\d+', '', $var)
怎么样? - mickmackusaecho bcdiv(3.22871, 1, 1); // 3.2
echo bcdiv(3.22871, 1, 2); // 3.22
echo bcdiv(3.22871, 1, 3); // 3.228
echo bcdiv(-3.22871, 1, 1); // -3.2
echo bcdiv(-3.22871, 1, 2); // -3.22
$var='2.500000550';
echo $var
echo bcdiv($var, 1, 2); // 2.50
number_format函数可以对数字进行四舍五入处理
php > echo number_format(128.20512820513, 2)."\n";
128.21
php > echo preg_replace('/(\.\d\d).*/', '$1', 128.20512820513)."\n";
128.20
使用number_format进行尝试:
echo number_format('2.50000050', 2); // 2.50
有人在这里发布了一个关于
floor(2.500000550 * 100) / 100;
的帖子。
这段代码是将 2.500000550 向下取整到小数点后两位(即保留两位小数),结果为 2.50。
function cutAfterDot($number, $afterDot = 2){
$a = $number * pow(10, $afterDot);
$b = floor($a);
$c = pow(10, $afterDot);
echo "a $a, b $b, c $c<br/>";
return $b/$c ;
}
echo cutAfterDot(2.05,2);
a 205, b 204, c 100
2.04
所以在原始形式下不要使用它... 但是如果你添加一点 epsilon...
function cutAfterDot($number, $afterDot = 2){
return floor($number * pow(10, $afterDot) + 0.00001) / pow(10, $afterDot);
}
它能正常工作!
floor(205)
为什么返回204的解释可以在http://php.net/manual/en/function.floor.php#114204找到。 - Sepstersprintf()
、number_format()
(以及显然的round()
)都执行舍入操作,因此不适合于问题中所需的非舍入截断(至少不是单独使用)。pow()
来获取基于指定精度的正确因子,从而使前一个解决方案更加通用)。floor()
(或可能的ceil()
)的方法,在没有使用abs()
的情况下可能会产生意想不到的结果。abs()
上的除法来获取否定因子,则需要考虑输入为0的特殊情况。。
public static function truncate_decimal($number, $leavePlaces = 2)
{
if ($number == 0) return 0;
$negate = $number / abs($number);
$shiftFactor = pow(10, $leavePlaces);
$epsilon = pow(10, -1 * $leavePlaces);
return floor(abs($number) * $shiftFactor + $epsilon) / $shiftFactor * $negate;
}
使用sprintf
sprintf("%01.2f", $var);
$var == 2.509
,则上述代码将返回2.51而不是2.50。因此,它无法回答明确声明“不要四舍五入”的问题。 - Sepster已经有很多可能的解决方案了,我只想添加我自己想出来的解决方案来解决我的问题。
function truncate_decimals($number, $decimals=2)
{
$factor = pow(10,$decimals);
$val = intval($number*$factor)/$factor;
return $val;
}
truncate_decimals(199.9349,2);
// 199.93