我在php变量中有这样的值
$var='2.500000550';
echo $var
我想要的是删除 2 位数字后的所有小数点。
就像现在变量的值将是
$var='2.50';
echo $var
请记住,此值来自 MySQL DataBSE
但是当我使用 round php function
我得到了圆形,但我不需要圆形,我只需要删除 2 个小数点后的所有数字。
我已经累了,flot()
和许多其他选择都没有成功。
谢谢
TL;DR:
PHP 本机函数 bcdiv 似乎可以准确地执行所需的操作,并且正确执行。
要简单地"截断"一个数字,bcdiv($var, 1, 2);
其中 2 是要保留的小数位数(1 是分母 - 将数字除以 1 允许您简单地将原始数字截断到所需的小数位(
完整答案(历史(
事实证明,这比人们想象的更难以捉摸。
在这个答案(错误地(被点赞之后,我注意到即使是 sprintf 也会四舍五入。
我没有删除这个答案,而是把它变成对每个建议的解决方案的更有力的解释/讨论。
number_format - 不正确。(回合(
尝试使用数字格式:
$var = number_format($var, 2, '.', ''); // Last two parameters are optional
echo $var;
// Outputs 2.50
如果您希望它是一个数字,那么只需将类型转换为浮点数:
$var = (float)number_format($var, 2, '.', '');
注意:正如评论中指出的那样,这实际上是四舍五入的数字。
冲刺 - 不正确。(冲刺也回合(
如果不对数字进行四舍五入很重要,那么根据下面的答案,使用 sprintf:
$var = sprintf("%01.2f", $var);
地板 - 不完全是!(地板四舍五入负数(
地板,加上一些数学,将接近做你想做的事:
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
floor(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"
尝试使用number_format:
echo number_format('2.50000050', 2); // 2.50
number_format对数字进行四舍五入
php > echo number_format(128.20512820513, 2)."'n";
128.21
我用preg_replace真的剪断了绳子
php > echo preg_replace('/('.'d'd).*/', '$1', 128.20512820513)."'n";
128.20
使用 PHP 本机函数 bcdiv。
例:
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
有人在这里发布关于
地板(2.500000550 * 100(/100;
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);
}
它有效!
使用 sprintf
sprintf("%01.2f", $var);
以下是(我相信的是 - 如果不是,请纠正我(一个强大的数学*解决方案,主要基于这里其他几个回答者的信息,以及我的少量信息。
(*这并不是说 Liphtier 基于正则表达式的答案有什么问题 - 只是我可以看到纯粹主义者想要避免正则表达式,因为可以说是一个数学问题。
-
sprintf()
,number_format()
(显然还有round()
(都在执行舍入操作,因此不适合问题中请求的非舍入截断(至少不是单独(。 - 代替开箱即用的功能,看似最优雅的解决方案是Sujit Agarwal的答案。
- 但是由于浮点数的存储方式,我们需要使用 epsilon - 正如 David Constantine 的回答中所指出的那样(他还通过使用
pow()
根据指定的精度获得正确的因子,使前面的解决方案更加通用(。 - 但是,正如cale_b的回答所指出的那样,任何使用
floor()
(或可能ceil()
(都可能在不使用abs()
的情况下对负面产生意想不到的结果。 - 我试图添加的值是:
- 如果使用除法
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;
}
已经有很多可能的解决方案,我只想添加我想出来解决我的问题的解决方案。
function truncate_decimals($number, $decimals=2)
{
$factor = pow(10,$decimals);
$val = intval($number*$factor)/$factor;
return $val;
}
truncate_decimals(199.9349,2);
// 199.93
使用number_format的解决方案都是错误的,因为number_format执行舍入。
下面的函数应该适用于所有数字,您可以为那些使用","的国家/地区指定小数分隔符。
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);
}
一个简单的函数是"如果大于 0 楼层,否则 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;
}
$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;
地板 - 不完全是!(地板四舍五入负数(
cale_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);
}
<小时 /> 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);
}
阳性
速率: 0.00302471
楼层: 0.00302400
塞伊尔: 0.00302500
阴性
速率: -0.00302471
楼层: -0.00302400
塞伊尔: -0.00302500
如果您不想对数字进行四舍五入,但要删除小数位,则可以使用"substr"方法
substr(string, start, length);
substr(4.96, 0, -1);