-
-
Save RadGH/84edff0cc81e6326029c to your computer and use it in GitHub Desktop.
<?php | |
// Converts a number into a short version, eg: 1000 -> 1k | |
// Based on: http://stackoverflow.com/a/4371114 | |
function number_format_short( $n, $precision = 1 ) { | |
if ($n < 900) { | |
// 0 - 900 | |
$n_format = number_format($n, $precision); | |
$suffix = ''; | |
} else if ($n < 900000) { | |
// 0.9k-850k | |
$n_format = number_format($n / 1000, $precision); | |
$suffix = 'K'; | |
} else if ($n < 900000000) { | |
// 0.9m-850m | |
$n_format = number_format($n / 1000000, $precision); | |
$suffix = 'M'; | |
} else if ($n < 900000000000) { | |
// 0.9b-850b | |
$n_format = number_format($n / 1000000000, $precision); | |
$suffix = 'B'; | |
} else { | |
// 0.9t+ | |
$n_format = number_format($n / 1000000000000, $precision); | |
$suffix = 'T'; | |
} | |
// Remove unecessary zeroes after decimal. "1.0" -> "1"; "1.00" -> "1" | |
// Intentionally does not affect partials, eg "1.50" -> "1.50" | |
if ( $precision > 0 ) { | |
$dotzero = '.' . str_repeat( '0', $precision ); | |
$n_format = str_replace( $dotzero, '', $n_format ); | |
} | |
return $n_format . $suffix; | |
} | |
/* | |
Example Usage: | |
number_format_short(7201); // Output: 7.2k | |
Demo: | |
echo '<table>'; | |
for($d = 0; $d < 16; $d++ ) { | |
$n = intval("09" . str_repeat( "0", $d )); | |
$n = $n / 10; | |
echo number_format_short($n) .'<br>'; // 0.9 | |
$n = intval("1" . str_repeat( "0", $d )); | |
echo number_format_short($n) .'<br>'; // 1.0 | |
$n = intval("11" . str_repeat( "0", $d ));; | |
$n = $n / 10; | |
echo number_format_short($n) .'<br>'; // 1.1 | |
} | |
echo '</table>'; | |
Demo Output: | |
0.9 | |
1 | |
1.1 | |
9 | |
10 | |
11 | |
90 | |
100 | |
110 | |
0.9K | |
1K | |
1.1K | |
9K | |
10K | |
11K | |
90K | |
100K | |
110K | |
0.9M | |
1M | |
1.1M | |
9M | |
10M | |
11M | |
90M | |
100M | |
110M | |
0.9B | |
1B | |
1.1B | |
9B | |
10B | |
11B | |
90B | |
100B | |
110B | |
0.9T | |
1T | |
1.1T | |
9T | |
10T | |
11T | |
90T | |
100T | |
110T | |
900T | |
1,000T | |
1,100T | |
*/ |
Thanks for this nice function. It works and is very helpful.
Thanks for sharing!
FYI I'm building a Laravel package on top of @hassanamirkhan's comment.
@hassanamirkhan in your snippet if ($n > 0 && $n < 1000) {
should be if ($n >= 0 && $n < 1000) {
to include the case when $n = 0
.
So:
/**
* @param $n
* @return string
* Use to convert large positive numbers in to short form like 1K+, 100K+, 199K+, 1M+, 10M+, 1B+ etc
*/
function number_format_short( $n ) {
if ($n >= 0 && $n < 1000) {
// 1 - 999
$n_format = floor($n);
$suffix = '';
} else if ($n >= 1000 && $n < 1000000) {
// 1k-999k
$n_format = floor($n / 1000);
$suffix = 'K+';
} else if ($n >= 1000000 && $n < 1000000000) {
// 1m-999m
$n_format = floor($n / 1000000);
$suffix = 'M+';
} else if ($n >= 1000000000 && $n < 1000000000000) {
// 1b-999b
$n_format = floor($n / 1000000000);
$suffix = 'B+';
} else if ($n >= 1000000000000) {
// 1t+
$n_format = floor($n / 1000000000000);
$suffix = 'T+';
}
return !empty($n_format . $suffix) ? $n_format . $suffix : 0;
}
Thanks everyone for this post... i edited the answer from @sandervanhooft
what i did is that i removed the + sign in case if is a round number... like 1000. but if it's 1023 it will add the + sign
Here is my code
//the first function is just removing .0 if is not a real number.
function mny2($value){
$value = sprintf("%0.1f", $value);
$vl = explode(".", $value);
$value = number_format($vl[0]);
if($vl[1]!="0")$value.=".".$vl[1];
return $value;
}
function NC($n,$precision=1) {
// the length of the n
$len = strlen($n);
// getting the rest of the numbers
$rest = (int)substr($n,$precision+1,$len);
// checking if the numbers is integer yes add + if not nothing
$checkPlus = (is_int($rest) and !empty($rest))?"+":"";
if ($n >= 0 && $n < 1000) {
// 1 - 999
$n_format = number_format($n);
$suffix = '';
} else if ($n >= 1000 && $n < 1000000) {
// 1k-999k
$n_format = number_format($n / 1000,$precision);
$suffix = 'K'.$checkPlus;
} else if ($n >= 1000000 && $n < 1000000000) {
// 1m-999m
$n_format = number_format($n / 1000000,$precision);
$suffix = 'M'.$checkPlus;
} else if ($n >= 1000000000 && $n < 1000000000000) {
// 1b-999b
$n_format = number_format($n / 1000000000);
$suffix = 'B'.$checkPlus;
} else if ($n >= 1000000000000) {
// 1t+
$n_format = number_format($n / 1000000000000);
$suffix = 'T'.$checkPlus;
}
return !empty($n_format . $suffix) ? mny2($n_format) . $suffix: 0;
}
Each time I see an else
statement, I think it's worth to re-write the code.
Here is a gist with my version: https://gist.github.com/komarnicki/49f70c4c2f60efa31b4a967077ea2ffa.
I'm sorry but in my opinion all you've managed to do is complicate a very simple function. What's your reason for avoiding else statements? And what is the point of having the anonymous function within the original function in your example?
@hassanamirkhan Thanks for this beautiful function.
@havutcuoglu, @hayjay and @sandervanhooft you're most welcome guys!
@hassanamirkhan in your snippet
if ($n > 0 && $n < 1000) {
should beif ($n >= 0 && $n < 1000) {
to include the case when$n = 0
.So:
/** * @param $n * @return string * Use to convert large positive numbers in to short form like 1K+, 100K+, 199K+, 1M+, 10M+, 1B+ etc */ function number_format_short( $n ) { if ($n >= 0 && $n < 1000) { // 1 - 999 $n_format = floor($n); $suffix = ''; } else if ($n >= 1000 && $n < 1000000) { // 1k-999k $n_format = floor($n / 1000); $suffix = 'K+'; } else if ($n >= 1000000 && $n < 1000000000) { // 1m-999m $n_format = floor($n / 1000000); $suffix = 'M+'; } else if ($n >= 1000000000 && $n < 1000000000000) { // 1b-999b $n_format = floor($n / 1000000000); $suffix = 'B+'; } else if ($n >= 1000000000000) { // 1t+ $n_format = floor($n / 1000000000000); $suffix = 'T+'; } return !empty($n_format . $suffix) ? $n_format . $suffix : 0; }
@sandervanhooft yep we can add $n >= 0.
But if you check ternary condition in return statement it is already handling $n=0 case.
love this function thanks
I made an approach to use as a realtime facade in Laravel, but I've adapted it to be used in any project. Feel free to take a look here: https://gist.github.com/maurobaptista/1c7ec5e71bac9bd20137cd01d390bdaa
just use (new NumberFormatter('en_US', NumberFormatter::PADDING_POSITION))->format($count)
Division is more costly than multiplication, https://stackoverflow.com/questions/4125033/floating-point-division-vs-floating-point-multiplication#answer-4125074
For better performance use multiplication where its possible.
// Converts a number into a short version, eg: 1000 -> 1k
// Based on: http://stackoverflow.com/a/4371114
function number_format_short($n, $precision = 1) {
if ($n < 900) {
// 0 - 900
$n_format = number_format($n, $precision);
$suffix = '';
} elseif ($n < 900000) {
// 0.9k-850k
$n_format = number_format($n * 0.001, $precision);
$suffix = 'K';
} elseif ($n < 900000000) {
// 0.9m-850m
$n_format = number_format($n * 0.000001, $precision);
$suffix = 'M';
} elseif ($n < 900000000000) {
// 0.9b-850b
$n_format = number_format($n * 0.000000001, $precision);
$suffix = 'B';
} else {
// 0.9t+
$n_format = number_format($n * 0.000000000001, $precision);
$suffix = 'T';
}
// Remove unecessary zeroes after decimal. "1.0" -> "1"; "1.00" -> "1"
// Intentionally does not affect partials, eg "1.50" -> "1.50"
if ($precision > 0) {
$dotzero = '.' . str_repeat('0', $precision);
$n_format = str_replace($dotzero, '', $n_format);
}
return $n_format . $suffix;
}
I modify it like below, because i don't want decimal and 999 inclusive in case of 999K+ instead of 0.9M and similarly for other M+, B+ and T+ etc