在 PHP 中从小数中删除无用的零位

我正在尝试找到一种快速的方法去除像这样的数值 zero decimals:

echo cleanNumber('125.00');
// 125


echo cleanNumber('966.70');
// 966.7


echo cleanNumber(844.011);
// 844.011

是否存在一些优化的方法来做到这一点?

157217 次浏览

你可以使用 floatval函数

echo floatval('125.00');
// 125


echo floatval('966.70');
// 966.7


echo floatval('844.011');
// 844.011

您应该将数字投射为浮点数,这将为您完成此操作。

$string = "42.422005000000000000000000000000";
echo (float)$string;

这个输出将是您正在寻找的。

42.422005

$num + 0就行了。

echo 125.00 + 0; // 125
echo '125.00' + 0; // 125
echo 966.70 + 0; // 966.7

在内部,这相当于使用 (float)$numfloatval($num)进行浮点转换,但我发现它更简单。

复杂但有效:

$num = '125.0100';
$index = $num[strlen($num)-1];
$i = strlen($num)-1;
while($index == '0') {
if ($num[$i] == '0') {
$num[$i] = '';
$i--;
}


$index = $num[$i];
}


//remove dot if no numbers exist after dot
$explode = explode('.', $num);
if (isset($explode[1]) && intval($explode[1]) <= 0) {
$num = intval($explode[0]);
}


echo $num; //125.01

上面的解决方案是最佳的方法,但如果你想拥有自己的,你可以使用这个。这个算法从字符串的末尾开始检查它的 0是否设置为空字符串然后从后面到下一个字符直到最后一个字符是 > 0

简单地将 +添加到字符串变量将导致对 (浮动)进行类型转换并删除零:

var_dump(+'125.00');     // double(125)
var_dump(+'966.70');     // double(966.7)
var_dump(+'844.011');    // double(844.011)
var_dump(+'844.011asdf');// double(844.011)

我用的是这个:

function TrimTrailingZeroes($nbr) {
return strpos($nbr,'.')!==false ? rtrim(rtrim($nbr,'0'),'.') : $nbr;
}

注意。这里假设 ABc0是小数点。它的优点是,它可以处理任意大(或小)的数字,因为不存在浮点类型转换。它也不会把数字变成科学记数法(例如1.0e-17)。

$x = '100.10';
$x = preg_replace("/\.?0*$/",'',$x);
echo $x;

没有什么是不能用简单的正则表达式修复的;)

Http://xkcd.com/208/

对于每一个来到这个网站有同样问题的逗号,改变:

$num = number_format($value, 1, ',', '');

致:

$num = str_replace(',0', '', number_format($value, 1, ',', '')); // e.g. 100,0 becomes 100


如果有 两个零需要删除,则改为:

$num = str_replace(',00', '', number_format($value, 2, ',', '')); // e.g. 100,00 becomes 100

详情请浏览: PHP 编号: 只有在需要时才能看到小数点

类型转换为 float

$int = 4.324000;
$int = (float) $int;

这就是我的小办法。 可以包含到类中并设置 vars

Private $dsepparator =’.’;//小数 Private $tsepparator =’,’;//million

可由构造函数设置并更改为用户 lang。

class foo
{
private $dsepparator;
private $tsepparator;


function __construct(){
$langDatas = ['en' => ['dsepparator' => '.', 'tsepparator' => ','], 'de' => ['dsepparator' => ',', 'tsepparator' => '.']];
$usersLang = 'de'; // set iso code of lang from user
$this->dsepparator = $langDatas[$usersLang]['dsepparator'];
$this->tsepparator = $langDatas[$usersLang]['tsepparator'];
}


public function numberOmat($amount, $decimals = 2, $hideByZero = false)
{
return ( $hideByZero === true AND ($amount-floor($amount)) <= 0 ) ? number_format($amount, 0, $this->dsepparator, $this->tsepparator) : number_format($amount, $decimals, $this->dsepparator, $this->tsepparator);
}
/*
* $bar = new foo();
* $bar->numberOmat('5.1234', 2, true); // returns: 5,12
* $bar->numberOmat('5', 2); // returns: 5,00
* $bar->numberOmat('5.00', 2, true); // returns: 5
*/


}

如果要在页面或模板上显示之前删除零位数。

您可以使用 Sprintf ()函数

sprintf('%g','125.00');
//125


‌‌sprintf('%g','966.70');
//966.7


‌‌‌‌sprintf('%g',844.011);
//844.011

此代码将删除后点零,并将只返回两个十进制数字。

$number = 1200.0000;
Str _ place (’.00’,”,number _ format ($number,2,’.’,”) ;

产量将是: 1200

$value = preg_replace('~\.0+$~','',$value);

你可使用:

print (floatval)(number_format( $Value), 2 ) );
$str = 15.00;
$str2 = 14.70;
echo rtrim(rtrim(strval($str), "0"), "."); //15
echo rtrim(rtrim(strval($str2), "0"), "."); //14.7

由于这个问题是旧的。首先,我很抱歉这一点。

问题是关于数字 xxx.xx,但是如果是 x,xxx.xxxxx 或者像 xxxx,xxxx 这样的差小数点,就很难找到并从十进制数中去掉零位数。

/**
* Remove zero digits (include zero trails - 123.450, 123.000) from decimal value.
*
* @param string|int|float $number The number can be any format, any where use in the world such as 123, 1,234.56, 1234.56789, 12.345,67, -98,765.43
* @param string The decimal separator. You have to set this parameter to exactly what it is. For example: in Europe it is mostly use "," instead of ".".
* @return string Return removed zero digits from decimal value. Only return as string!
*/
function removeZeroDigitsFromDecimal($number, $decimal_sep = '.')
{
$explode_num = explode($decimal_sep, $number);
if (is_countable($explode_num) && count($explode_num) > 1) {
// if exploded number is more than 1 (Example: explode with . for nnnn.nnn is 2)
// replace `is_countable()` with `is_array()` if you are using PHP older than 7.3.
$explode_num[count($explode_num)-1] = preg_replace('/(0+)$/', '', $explode_num[count($explode_num)-1]);
if ($explode_num[count($explode_num)-1] === '') {
// if the decimal value is now empty.
// unset it to prevent nnn. without any number.
unset($explode_num[count($explode_num)-1]);
}
$number = implode($decimal_sep, $explode_num);
}
unset($explode_num);
return (string) $number;
}

这是测试代码。

$tests = [
1234 => 1234,
-1234 => -1234,
'12,345.67890' => '12,345.6789',
'-12,345,678.901234' => '-12,345,678.901234',
'12345.000000' => '12345',
'-12345.000000' => '-12345',
'12,345.000000' => '12,345',
'-12,345.000000000' => '-12,345',
];
foreach ($tests as $number => $assert) {
$result = removeZeroDigitsFromDecimal($number);
assert($result === (string) $assert, new \Exception($result . ' (' . gettype($result) . ') is not matched ' . $assert . ' (' . gettype($assert) . ')'));
echo $number . ' =&gt; ' . (string) $assert . '<br>';
}


echo '<hr>' . PHP_EOL;


$tests = [
1234 => 1234,
-1234 => -1234,
'12.345,67890' => '12.345,6789',
'-12.345.678,901234' => '-12.345.678,901234',
'12345,000000' => '12345',
'-12345,000000' => '-12345',
'-12.345,000000000' => '-12.345',
'-12.345,000000,000' => '-12.345,000000',// this is correct assertion. Weird ,000000,000 but only last 000 will be removed.
];
foreach ($tests as $number => $assert) {
$result = removeZeroDigitsFromDecimal($number, ',');
assert($result === (string) $assert, new \Exception($result . ' (' . gettype($result) . ') is not matched ' . $assert . ' (' . gettype($assert) . ')'));
echo $number . ' =&gt; ' . (string) $assert . '<br>';
}

所有测试都应该通过,没有错误。

为什么 '-12.345,000000,000'会是 '-12.345,000000'而不是 '-12.345'
因为此函数用于从十进制值中删除零位(包括零尾)。不是对正确的数字格式进行验证。那应该是另一个功能。

为什么总是以字符串的形式返回?
因为在计算中最好使用 bcxxx函数,或者使用大数。

小心添加 + 0。

echo number_format(1500.00, 2,".",",")+0;
//1

结果是1。

echo floatval('1,000.00');
// 1


echo floatval('1000.00');
//1000

这就是我的解决办法。 我要保持能力,添加千分离器

    $precision = 5;
$number = round($number, $precision);
$decimals = strlen(substr(strrchr($number, '.'), 1));
return number_format($number, $precision, '.', ',');

这是一个简单的单行函数,使用的是 rrim,保存分隔符和小数点:

function myFormat($num,$dec)
{
return rtrim(rtrim(number_format($num,$dec),'0'),'.');
}

我发现这个解决方案是最好的:

public function priceFormat(float $price): string
{
//https://stackoverflow.com/a/14531760/5884988
$price = $price + 0;
$split = explode('.', $price);
return number_format($price, isset($split[1]) ? strlen($split[1]) : 2, ',', '.');
}

简单又准确!

function cleanNumber($num){
$explode = explode('.', $num);
$count   = strlen(rtrim($explode[1],'0'));
return bcmul("$num",'1', $count);
}

最终解决方案: 唯一安全的方法是使用 regex:

echo preg_replace("/\.?0+$/", "", 3.0); // 3
echo preg_replace("/\d+\.?\d*(\.?0+)/", "", 3.0); // 3

这对任何情况都有效

以下内容要简单得多

if(floor($num) == $num) {
echo number_format($num);
} else {
echo $num;
}

你可以尝试以下方法:

rtrim(number_format($coin->current_price,6),'0.')

我使用这个简单的代码:

define('DECIMAL_SEPARATOR', ','); //To prove that it works with different separators than "."


$input = "50,00";


$number = rtrim($input, '0');                // 50,00 --> 50,
$number = rtrim($number, DECIMAL_SEPARATOR); // 50,   --> 50


echo $number;

似乎有点太容易成为 真的正确的解决方案,但它的工作正好适合我。在使用这个命令之前,您应该对将要获得的输入进行一些测试。

例子一

$value =81,500.00;
\{\{rtrim(rtrim(number_format($value,2),0),'.')}}

输出

81500

例子2

$value=110,763.14;
\{\{rtrim(rtrim(number_format($value,2),0),'.')}}

输出

110,763.14

有时,特别是在货币金额的情况下,只有当0为2时,才需要删除它们,因为不想打印 € 2.1而不是 € 2.10

执行方式可以是:

function formatAmount(string|float|int $value, int $decimals = 2): string
{
if (floatval(intval($value)) === floatval($value)) {
// The number is an integer. Remove all the decimals
return (string)intval($value);
}


return number_format($value, $decimals);
}

预期产出实例:

0.1000 => 0.10
20.000 => 20
1.25 => 1.25

假设金额是一个小数点后两位的字符串,那么您可以使用:

protected function removeZerosDecimals(string $money): string
{
$formatter = new NumberFormatter('en_US', NumberFormatter::CURRENCY);


$uselessDecimals = sprintf(
'%s00',
$formatter->getSymbol(NumberFormatter::DECIMAL_SEPARATOR_SYMBOL)
);
if (!str_ends_with($money, $uselessDecimals)) {
return $money;
}


$len = mb_strlen($money);
return mb_substr($money, 0, $len - mb_strlen($uselessDecimals));
}

对于任何货币,如 $500.00R$ 500,00,这都是可以预期的。