Reputation: 645
Is there a built-in/neat way to format a number (just like number_format
does), but without any rounding ups/downs?
For instance, number 1234.234
should be formatted as 1,234.234
and another number 1234
should be formatted as 1,234
(i.e. without any trailing .000
)
Upvotes: 3
Views: 4369
Reputation: 1769
Based on the arhey's answer
TLDR ;)
You can use number_format
to format the number to a fixed-width format, then use rtrim
twice to remove trailing zeroes, and dot.
rtrim(rtrim(number_format($number, 3, '.', ','), '0'), '.')
Starting from the last character, rtrim removes it while it is one of those given. In our case, we remove trailing dots, then we remove an eventual trailing zero.
rtrim(rtrim(number_format(1234.123, 3, '.', ','), '0'), '.')
// returns 1,234.123
rtrim(rtrim(number_format(1234.12, 3, '.', ','), '0'), '.')
// returns 1,234.12 (1,234.120, trimmed to 1234.12)
rtrim(rtrim(number_format(1234, 3, '.', ','), '0'), '.')
// returns 1,234 (1,234.000, trimmed to 1234)
rtrim(rtrim(number_format(1200, 3, '.', ','), '0'),'.')
// returns 1,200 (1,200.000, trimmed to 1200., trimmed to 1200)
Formal form, and discussion about the parameters (notably the decimals count)
rtrim(rtrim(number_format($number, <N>, '<D>', ''), '0'), '<D>')
Where :
If you know all your numbers will have less than 3 digits, go and take N=3.
What if you don't know how many decimals are at most ? Well, things are getting more complex. It may worth recalling (as stated in the PHP documentation) that floats are stored :
For example, floor((0.1+0.7)*10) will usually return 7 instead of the expected 8, since the internal representation will be something like 7.9999999999999991118....
So there is no universal good value, you'll have to choose it depending on the usual scale of your data.
And that explains why there is no built-in function for that : PHP can't choose for you.
Upvotes: 4
Reputation: 232
I really liked arhey's answer, but later realized it has a major flaw. A number like 2100
will get converted to 2,1
instead of 2,100
.
Below is how I ended up modifying it.
public function formatDecimal($number)
{
$stringVal = strval($number); //convert number to string
$decPosition = strpos($stringVal, ".");
if ($decPosition !== false) //there is a decimal
{
$decPart = substr($stringVal, $decPosition); //grab only the decimal portion
$result = number_format($stringVal) . rtrim($decPart, ".0");
}
else //no decimal to worry about
{
$result = number_format($stringVal);
}
return $result;
}
It's not as succinct a solution as I was hoping, but in my case I put it into a view helper (I'm using ZF2) and so it's just one simple function call in my view.
Hope this is helpful for someone!
Upvotes: 1
Reputation: 2579
You can use function:
<?php
function getNumberFormat($number) {
$numberAr = explode('.', (string)$number);
$count = 0;
if (2 === count($numberAr)) {
$count = strlen($numberAr[1]);
}
return number_format($number, $count, ',', '.');
}
$test1 = 1234.234;
$test2 = 1234;
echo getNumberFormat($test1); //1,234.234
echo getNumberFormat($test2); //1,234
Upvotes: 2
Reputation: 311
rtrim(number_format(1234.234, 3),'.0');
rtrim(number_format(1234, 3),'.0');
Upvotes: 0
Reputation: 15656
Let's begin with that there's no decimal type in PHP. There's float only.
And if you know how float works, then you know that it's usually not possible to store exact decimal value that you think you have, but it's an approximation. That's because you can't express most of decimal numbers in binary system.
Therefore if you say:
$number = 1234.234;
Then you have a float that is close to this value. The real value is:
1234.23399999999992360244505107402801513671875
Therefore PHP can't just guess how do you want to round it. It needs to be specified explicitly.
Upvotes: 0
Reputation: 5316
You can define simple custom function for that:
<?php
function custom_number_format($number, $decimal = '.')
{
$broken_number = explode($decimal, $number);
if (isset($broken_number[1]))
return number_format($broken_number[0]) . $decimal . $broken_number[1];
else
return number_format($broken_number[0]);
}
$n1 = '1234.234';
$n2 = '1234';
echo custom_number_format($n1);
echo '<br>';
echo custom_number_format($n2);
?>
Output is:
1,234.234
1,234
Upvotes: 4