【问题标题】:How to calculate/display number as "Top 5", "Top 10", "Top 15" and so on?如何计算/显示数字为“前 5 名”、“前 10 名”、“前 15 名”等?
【发布时间】:2020-02-15 11:00:37
【问题描述】:

您将如何创建一个函数(在 PHP 中)以返回适当的舍入排名组的值(例如“前 5”、“前 10”、“前 15”、...“前 100 万”、“前 500 万”、“前 1000 万”、“前 1500 万”)。

请注意,它应该四舍五入到最接近的 1、5 或 10 - 例如“前 1500 万”而不是“前 1200 万”。

例子:

排名 = 输出

  • 1-5 = 5(前 5 名)
  • 6-10 = 10(前 10 名)
  • 11-15 = 15(排名前 15)

这应该一直有效到数万亿。

我当前的函数工作(有点)但是它会返回一个前 15 名的排名组作为前 20 名的值。

   private function format_number_iollions($amount,$style=null) {
        $amount = (0 + str_replace(',', '', $amount));   
        if (!is_numeric($amount)){
            return false;
        }

        $plusString = '';
        switch ($style){
            case 'plus':
                $plusString = '+';
            break;
        }

        if ($style==='rank' && $amount<=10){
            return 10;
        }

        // filter and format it 
        if ($amount>1000000000000){

            if ($style==='rank'){
                $v = ceil(($amount/1000000000000));
            } else {
                $v = floor(($amount/1000000000000));
            }

            $v .= $plusString.' trillion';
        } else if ($amount>1000000000){ 
            if ($style==='rank'){
                $v = ceil(($amount/1000000000));
            } else {
                $v = floor(($amount/1000000000));
            }

            $v .= $plusString.' billion';
        } else if ($amount>1000000){ 
            if ($style==='rank'){
                $v = ceil(($amount/1000000));
            } else {
                $v = floor(($amount/1000000));
            }

            $v .= $plusString.' million';
        } else if ($amount>100000){ 
            if ($style==='rank'){
                $v = ceil(($amount/100000));
            } else {
                $v = floor(($amount/100000));
            }

            $v .= '00,000'.$plusString;
        } else if ($amount>10000){ 
            if ($style==='rank'){
                $v = ceil(($amount/10000));
            } else {
                $v = floor(($amount/10000));
            }

            $v .= '0,000'.$plusString;
        } else if ($amount>1000){ 
            if ($style==='rank'){
                $v = ceil(($amount/1000));
            } else {
                $v = floor(($amount/1000));
            }

            $v .= ',000'.$plusString;
        } else if ($amount>100){ 
            if ($style==='rank'){
                $v = ceil(($amount/100));
            } else {
                $v = floor(($amount/100));
            }

            $v .= '00'.$plusString;
        } else if ($amount>10){ 
            if ($style==='rank'){
                $v = ceil(($amount/10));
            } else {
                $v = floor(($amount/10));
            }

            $v .= '0'.$plusString;
        } else {
            return number_format($amount);
        }

        return $v;
    }

UPDATE - 最终解决方案是这个功能(如果有人需要的话):

private function get_rank_group($rawrank) {
    // Divide by 1000 and count how many divisions were done
    $rank_scale = 0;
    while ($rawrank >= 1000) {
        $rawrank /= 1000;
        $rank_scale++;
    }
    // Determine which Top X can be
    if ($rawrank >= 100) {
        $lim_name = (floor(($rawrank-1) / 50) + 1) * 50;
    } else {
        $lim_name = (floor(($rawrank-1) / 5) + 1) * 5;
    }
    // if its in the next higher level
    if ($lim_name >= 1000) {
        $lim_name = '1';
        $rank_scale++; 
    }
    static $rank_scale_names = array('', ',000', ' Million', ' Billion', ' Trillion',  ' Quadrillion', ' Quintillion', ' Sextillion', ' Septillion');
    if (!isset($rank_scale_names[$rank_scale])){
        return null; //too much - add higher word-numbers to $rank_scale_names
    } else {
        return "$lim_name{$rank_scale_names[$rank_scale]}";
    }
}

【问题讨论】:

  • 使用 PHP 的 % 操作符。
  • 至少我不确定我完全理解应该是什么输出。您能否提供几个带有$amount 输入和所需输出的示例?

标签: php math


【解决方案1】:
<?php
  function get_rank_group($rawrank) {
     // Divide by 1000 and count how many divisions were done
     $rank_scale = 0;
     while ($rawrank >= 1000) {
       $rawrank /= 1000;
       $rank_scale++;
     }
     // Determine which Top X can be
     static $rank_split = array(3, 5, 10, 15, 20, 30, 50, 100, 150, 200, 300, 500); 
     $lim_name = false;
     // Look for a group, which is not less than the number
     foreach ($rank_split as $lim) { 
       if ($rawrank <= $lim) {
         $lim_name = $lim;
         break;
       }
     }
     // If nothing was found then it is a Top 1 of (next scaler) eg. 501 is Top 1 Thousand
     if ($lim_name === false) {
       $lim_name = '1';
       $rank_scale++;
     }
     static $rank_scale_names = array('', ' Thousand', ' Million', ' Billion', ' Trillion',  ' Quadrillion', ' Quintillion', ' Sextillion', ' Septillion'); // etc
     if (!isset($rank_scale_names[$rank_scale])) return 'too much!'; // just check
     return "Top $lim_name{$rank_scale_names[$rank_scale]}";
  }

  // Tests
  $tests = array(1, 2, 3, 4, 16, 49, 50, 51, 299, 300, 301, 12345, 654321, 234567890, 1234567890123456789);
  foreach ($tests as $test) {
    print ("$test -> " . get_rank_group($test) . PHP_EOL);
  }

输出:

1 -> Top 3
2 -> Top 3
3 -> Top 3
4 -> Top 5
16 -> Top 20
49 -> Top 50
50 -> Top 50
51 -> Top 100
299 -> Top 300
300 -> Top 300
301 -> Top 500
12345 -> Top 15 Thousand
654321 -> Top 1 Million
234567890 -> Top 300 Million
1234567890123456789 -> Top 3 Quintillion

【讨论】:

  • 谢谢 - 一个很好的解决方案。我将它与下面Turo的调整结合使用!
【解决方案2】:

作为对 AterLux 解决方案的改进

...
// Determine which Top X can be
if ($rawrank >= 100) {
    $lim_name = (floor(($rawrank-1) / 50) + 1) * 50;
} else {
    $lim_name = (floor(($rawrank-1) / 5) + 1) * 5;
}
// if its in the next higher level
if ($lim_name >= 1000) {
    $lim_name = '1';
    $rank_scale++; 
}
static $rank_scale_names = array( ...

输出

1 -> Top 5
5 -> Top 5
9 -> Top 10
10 -> Top 10
12 -> Top 15
16 -> Top 20
49 -> Top 50
50 -> Top 50
51 -> Top 55
299 -> Top 300
300 -> Top 300
301 -> Top 350
995 -> Top 1 Thousand
12345 -> Top 15 Thousand
654321 -> Top 700 Thousand
234567890 -> Top 250 Million
1234567890123456789 -> Top 5 Quintillion

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-16
    • 1970-01-01
    • 2012-05-20
    • 1970-01-01
    相关资源
    最近更新 更多