Php 删除两个小数点后的数字,但不舍入值
我在php变量中有这样的值Php 删除两个小数点后的数字,但不舍入值,php,function,rounding,Php,Function,Rounding,我在php变量中有这样的值 $var='2.500000550'; echo $var 我想要的是删除2位之后的所有小数点 像现在一样,变量的值将是 $var='2.50'; echo $var 请记住,此值来自mysql数据库 但是当我使用round php函数时我得到了round,但我不需要round,我只需要删除2位小数后的所有数字 我累了,flot()还有很多其他选择都没有成功 谢谢试试: 这将完成您的任务…使用 TL;博士: PHP本机函数似乎能够正确地完成所需的工作 为了简单地“
$var='2.500000550';
echo $var
我想要的是删除2位之后的所有小数点
像现在一样,变量的值将是
$var='2.50';
echo $var
请记住,此值来自mysql数据库
但是当我使用round php函数时
我得到了round,但我不需要round,我只需要删除2位小数后的所有数字
我累了,flot()
还有很多其他选择都没有成功
谢谢试试:
这将完成您的任务…使用
TL;博士:
PHP本机函数似乎能够正确地完成所需的工作
为了简单地“截断”一个数字,bcdiv($var,1,2)代码>其中2是要保留的小数位数(1是指代名词-将该数字除以1,可以简单地将原始数字截断为所需的小数位数)
完整答案(历史)
事实证明,这比人们想象的更加难以捉摸
在这个答案被(错误地)高估了一点之后,我注意到即使是sprintf也会被说服
我没有删除这个答案,而是将其转化为对每个建议解决方案的更有力的解释/讨论
数字\u格式-不正确。(轮数)
尝试使用:
如果希望它是一个数字,只需键入cast to a float:
$var = (float)number_format($var, 2, '.', '');
注意:正如评论中所指出的,这实际上是对数字的四舍五入
sprintf-不正确。(sprintf也会轮换)
如果数字不四舍五入很重要,那么根据下面的答案,使用:
地板-不太好!(底数为负数)
,再加上一些数学,将接近你想要的:
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
上述功能的结果:
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本机函数
有人在这里发布了关于
地板(2.500000550*100)/100
它起作用了 number\u格式将数字四舍五入
php > echo number_format(128.20512820513, 2)."\n";
128.21
我用preg_replace来真正切断绳子
php > echo preg_replace('/(\.\d\d).*/', '$1', 128.20512820513)."\n";
128.20
所有使用数字格式的解决方案都是错误的,因为数字格式执行舍入
下面的函数适用于所有数字,您可以为使用“,”的国家/地区指定十进制分隔符
function truncate_decimal($number, $truncate_decimal_length = 2, $decimal_character = '.', $thousands_character = '') {
$number = explode($decimal_character, $number);
$number[1] = substr($number[1], 0, $truncate_decimal_length);
$number_truncated = implode($decimal_character, $number);
return number_format($number_truncated, $truncate_decimal_length, $decimal_character, $thousands_character);
}
以下是(我相信是-如果不是请纠正我)一个稳健的数学*解决方案,主要基于其他几个回答者的信息,以及我的少量信息
(*这并不是说它有什么问题——只是我可以看到纯粹主义者想要避免使用正则表达式,因为这可能是一个数学问题。)
sprintf()
,number\u format()
(和round()
,显然)都在执行舍入操作,因此不适合问题中请求的非舍入截断(至少不是它们自己)
- 代替开箱即用的功能,看起来最优雅的解决方案是
- 但由于浮点数的存储方式,我们需要使用ε-正如中所指出的(他还通过使用
pow()
来获得基于指定精度的正确因子,从而使前面的解决方案更加通用)
- 但是,正如中所指出的,如果不使用
abs()
,任何使用floor()
(或者想必是ceil()
)的方法都可能产生意外的负片结果
- 我想增加的价值是:
- 如果在
abs()
上使用除法来获得一个求反因子,我们需要考虑输入为0时的特殊情况
- 我们应该动态地创建epsilon;静态硬编码epsilon可能太小或太大,这取决于所需的精度。我还没有看到其他答案中提到这个问题
我使用的代码是:
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;
}
您请求的函数返回的是“2.50”
,而不是2.5
,因此,这里讨论的不是算术,而是字符串操作。然后,preg\u 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"
一个简单的函数是“如果大于0 floor,else ceil”,在执行此操作时,使用乘数将其临时提高到小数点以上:
function trim_num($num_in, $dec_places = 2) {
$multiplier = pow(10, $dec_places); // 10, 100, 1000, etc
if ($num_in > 0) {
$num_out = floor($num_in * $multiplier) / $multiplier;
} else {
$num_out = ceil($num_in * $multiplier) / $multiplier;
}
return $num_out;
}
使用PHP本机函数
示例:
echo 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
地板-不太好!(底数为负数)
从刻度盘b答案中找到可能的解决方案
static public function rateFloor($rate, $decimals)
{
$div = "1" . str_repeat("0", $decimals);
if ($rate > 0) {
return floor($rate * $div) / $div;
}
$return = floor(abs($rate) * $div) / $div;
return -($return);
}
肯定的
比率:0.00302471
楼层:0.00302400
Ceil:0.00302500
否定的
费率:-0.00302471
楼层:-0.00302400
Ceil:-0.00302500
如果不想对数字进行四舍五入,但想删除小数点,可以使用“substr”方法
已经有很多可能的解决方案了,我只想添加一个解决我问题的方案
函数截断小数($number,$decimals=2)
{
$factor=pow(10,$decimals);
$val=intval($number*$factor)/$factor;
返回$val;
}
截断小数(199.9349,2);
// 199.93
您尝试过数字格式吗?它没有明确的文档记录,但数字格式是循环的。应该提到的是,数字格式返回的是字符串而不是数字。@MuhammadAtif-是的,这不是本文中的正确答案。正确的答案是bcdiv
顺便说一句,如果您只需要删除数字,那么bcadd($num\u FLO,0,$prec\u INT)是首选的,因为它比div或mul操作更快)@Bill\u VA-谢谢您的评论。事实上,我的代码是正确的(就像你的一样),我的代码遵循“防御”
$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"
function trim_num($num_in, $dec_places = 2) {
$multiplier = pow(10, $dec_places); // 10, 100, 1000, etc
if ($num_in > 0) {
$num_out = floor($num_in * $multiplier) / $multiplier;
} else {
$num_out = ceil($num_in * $multiplier) / $multiplier;
}
return $num_out;
}
echo 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
$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;
static public function rateFloor($rate, $decimals)
{
$div = "1" . str_repeat("0", $decimals);
if ($rate > 0) {
return floor($rate * $div) / $div;
}
$return = floor(abs($rate) * $div) / $div;
return -($return);
}
static public function rateCeil($rate, $decimals)
{
$div = "1" . str_repeat("0", $decimals);
if ($rate > 0) {
return ceil($rate * $div) / $div;
}
$return = ceil(abs($rate) * $div) / $div;
return -($return);
}
substr(string, start, length);
substr(4.96, 0, -1);