将长数字缩短为 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-&gt;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) &lt; ($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?的主要内容,如果未能解决你的问题,请参考以下文章

将长数字转换为短而紧凑的数字

将长十六进制字符串转换为十进制字符串

有没有办法用 CSS 将长数字(“$100000000”)分解成更易读的三元组(“$100 000 000”)?

如何在JavaScript中缩短长度数字[重复]

PHP 科学记数法缩短

Excel:格式化数字 - 缩短数字/删除数字