将长数字缩短为 K/M/B?
Posted
技术标签:
【中文标题】将长数字缩短为 K/M/B?【英文标题】:Shorten long numbers to K/M/B? 【发布时间】:2011-05-21 05:46:49 【问题描述】:我用谷歌搜索了很多,但根据我的查询,我找不到任何有用的功能。
我想要的是:
100 -> 100
1000 -> 1,000
142840 -> 142,840
但是
2023150 -> 2.023M ( i still want 3 additional numbers for more accuracy )
5430120215 -> 5.430B
如果可能的话,我非常感谢任何自定义函数来动态选择限制。
【问题讨论】:
你不是说Kilo/Mega/Giga
的“K/M/G”,而不是Thousand/Million/Billion
?
【参考方案1】:
使用number_format()
:
if ($n < 1000000)
// Anything less than a million
$n_format = number_format($n);
else if ($n < 1000000000)
// Anything less than a billion
$n_format = number_format($n / 1000000, 3) . 'M';
else
// At least a billion
$n_format = number_format($n / 1000000000, 3) . 'B';
如果可能的话,我非常感谢任何自定义函数来动态选择限制。
如果“limit”指的是小数位数(精度),那很简单:
function custom_number_format($n, $precision = 3)
if ($n < 1000000)
// Anything less than a million
$n_format = number_format($n);
else if ($n < 1000000000)
// Anything less than a billion
$n_format = number_format($n / 1000000, $precision) . 'M';
else
// At least a billion
$n_format = number_format($n / 1000000000, $precision) . 'B';
return $n_format;
【讨论】:
有趣!!出于好奇,对 Stack Exchange 如何计算它有任何想法吗? 不是官方的,但这可能是算法***.com/q/3177855/1671639【参考方案2】:Cakephp 有一个 Number Helper 和一个方法 toReadableSize
。你应该能够理解它并自己想出一些东西。其中$this->precision
基本类似于number_format()
,而__n
是单复数函数。
【讨论】:
【参考方案3】:我接受了 BoltClock 提供的答案,并在考虑到易于配置的情况下对其进行了一些调整。
// Shortens a number and attaches K, M, B, etc. accordingly
function number_shorten($number, $precision = 3, $divisors = null)
// Setup default $divisors if not provided
if (!isset($divisors))
$divisors = array(
pow(1000, 0) => '', // 1000^0 == 1
pow(1000, 1) => 'K', // Thousand
pow(1000, 2) => 'M', // Million
pow(1000, 3) => 'B', // Billion
pow(1000, 4) => 'T', // Trillion
pow(1000, 5) => 'Qa', // Quadrillion
pow(1000, 6) => 'Qi', // Quintillion
);
// Loop through each $divisor and find the
// lowest amount that matches
foreach ($divisors as $divisor => $shorthand)
if (abs($number) < ($divisor * 1000))
// We found a match!
break;
// We found our match, or there were no matches.
// Either way, use the last defined value for $divisor.
return number_format($number / $divisor, $precision) . $shorthand;
【讨论】:
很好的答案凯尔。不过要注意几点:您应该使用if(abs($number) < ($divisor * 1000))
,否则负数将永远不会缩短。此外,实例化$divisor
和$shortand
可能是个好主意,只是为了确保当用户可能传递一个空的$divisors
时不会出现异常。谢谢!
Lazily return 0 + number_format($number / $divisor, $precision) . $shorthand;
消除尾随无关紧要的零(在我的情况下我不需要)。
我还添加了一个回合,现在这就是我想要的:return 0 + round(number_format($number / $divisor, $precision),1) . $shorthand;
我不知道为什么,但是一旦这个数字越过十亿大关并触及万亿。此方法显示错误“遇到非格式正确的数值”【参考方案4】:
<?php
// Converts a number into a short version, eg: 1000 -> 1k
// Based on: http://***.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
*/
【讨论】:
【参考方案5】:你可以试试这个
function number_formation($number, $precision = 3)
if ($number < 1000000)
$formatted_number = number_format($number); /* less than a million */
else if ($number < 1000000000)
$formatted_number = number_format($number / 1000000, $precision) . 'M'; /* billion */
else
$formatted_number = number_format($number / 1000000000, $precision) . 'B'; /* for billion */
return $formatted_number;
【讨论】:
【参考方案6】:试试这个
function custom_number_format($n, $precision = 1)
if ($n < 900)
// Default
$n_format = number_format($n);
else if ($n < 900000)
// Thausand
$n_format = number_format($n / 1000, $precision). 'K';
else if ($n < 900000000)
// Million
$n_format = number_format($n / 1000000, $precision). 'M';
else if ($n < 900000000000)
// Billion
$n_format = number_format($n / 1000000000, $precision). 'B';
else
// Trillion
$n_format = number_format($n / 1000000000000, $precision). 'T';
return $n_format;
【讨论】:
【参考方案7】:function number_abbr($number)
$abbrevs = [12 => 'T', 9 => 'B', 6 => 'M', 3 => 'K', 0 => ''];
foreach ($abbrevs as $exponent => $abbrev)
if (abs($number) >= pow(10, $exponent))
$display = $number / pow(10, $exponent);
$decimals = ($exponent >= 3 && round($display) < 100) ? 1 : 0;
$number = number_format($display, $decimals).$abbrev;
break;
return $number;
适用于正面和负面。
【讨论】:
【参考方案8】:尽管很久以前有人问过这个问题,但我有一个不同的解决方案,我认为它更简单:
function shorten($number)
$suffix = ["", "K", "M", "B"];
$precision = 1;
for($i = 0; $i < count($suffix); $i++)
$divide = $number / pow(1000, $i);
if($divide < 1000)
return round($divide, $precision).$suffix[$i];
break;
echo shorten(1000);
我希望它仍然对某人有所帮助。
【讨论】:
【参考方案9】:试试这个。考虑组 k、M、B、T 和 Q(万亿)。任何高于 999Q 的都显示为 999Q+。
function number(float $num, int $precision = 2): string
$absNum = abs($num);
if ($absNum < 1000)
return (string)round($num, $precision);
$groups = ['k','M','B','T','Q'];
foreach ($groups as $i => $group)
$div = 1000 ** ($i + 1);
if ($absNum < $div * 1000)
return round($num / $div, $precision) . $group;
return '999Q+';
【讨论】:
【参考方案10】:我在之前的解决方案的基础上采取了不同的方法。基本上它使用log()
函数来摆脱for
语句:
function number_shorten($number, $precision = 3)
$suffixes = ['', 'K', 'M', 'B', 'T', 'Qa', 'Qi'];
$index = (int) log(abs($number), 1000);
$index = max(0, min(count($suffixes) - 1, $index)); // Clamps to a valid suffixes' index
return number_format($number / 1000 ** $index, $precision) . $suffixes[$index];
它适用于正数和负数。
【讨论】:
【参考方案11】:我重构了 OG 最佳答案,让它变得更好和一个功能
public function formatNumber($number)
if ($number < 1000000)
// Anything less than a million
return number_format($number);
else if ($number < 1000000000)
// Anything less than a billion
return number_format($number / 1000000, 0) . 'm';
else
// At least a billion
return number_format($number / 1000000000, 0) . 'b';
【讨论】:
【参考方案12】:这是一个非常适合我需要的修改版本。这使我可以指定是否希望 5,500,000 显示为“5.5M”(短样式)或“550 万”(长样式)。
function nice_number_format( $n, $style = 'short' )
if ($n < 1000)
$n_format = number_format($n);
else if ($n < 1000000)
$n_format = floatval(number_format($n / 1000, 2));
$suffix = ($style == 'long' ? ' thousand' : 'K');
else if ($n < 1000000000)
$n_format = floatval(number_format($n / 1000000, 2));
$suffix = ($style == 'long' ? ' million' : 'M');
else
$n_format = floatval(number_format($n / 1000000000, 2));
$suffix = ($style == 'long' ? ' billion' : 'B');
return $n_format . $suffix;
【讨论】:
【参考方案13】:一些修改$precision = 1, 2, 3 or 4 ...
function kmb($count, $precision = 2)
if ($count < 1000000)
// Anything less than a million
$n_format = number_format($count / 1000) . 'K';
else if ($count < 1000000000)
// Anything less than a billion
$n_format = number_format($count / 1000000, $precision) . 'M';
else
// At least a billion
$n_format = number_format($count / 1000000000, $precision) . 'B';
return $n_format;
回声 kmb(272937);
273K
回声 kmb(2729347);
273万
回声 kmb(2729347874);
2.73B
【讨论】:
以上是关于将长数字缩短为 K/M/B?的主要内容,如果未能解决你的问题,请参考以下文章