Shorten Amounts To Thousands (K), Millions (M), Billions (B), and Trillions (T)

Shortened Huge Amounts

Pictures they say are worth a thousand words, and the featured image at the top should clearly communicate what this piece is all about – that is shortening huge amounts into summarized versions.


The devil lies is in the details (like the ones in the number cloud inserted), but there are situations where those details are quite unnecessary such as where displaying huge amounts – like 123,440,782,000 – in a chart or a summary report could be more helpful if a shortened version – i.e. 123.44B or 123B depending on the decimal places specified – is used which will still convey the intended meaning to the audience.

If you want to be able to shorten huge amounts for some of the reasons in the foregoing paragraph, then you are at the right place. In fact, it is that simple to do.

The Approach

One way of looking at this is to start from the highest unit, trillions, to the lowest unit, thousands, to determine where a given amount falls. The natural thinking in this approach is that if a number is not in the trillions, it’ll probably be in the billions, or millions, or in the thousands, etc.

In determining the correct unit for a given amount, simply divide the amount by the unit representation (the lowest amount that makes up that unit, e.g. 1,000 for thousands unit) and if the remainder is greater than or equal to 1, then the amount is in that unit, otherwise move onto the immediate lower unit and repeat the process.

The Walk-through

Finding the correct unit for 52,000,000 (Fifty-Two Million) is demonstrated below in the same order in which the algorithm to be implemented will be looking at the provided amount. 
The left column shows the computational operation and the right column shows the result of the test whether the remainder is greater than or equal to 1 which is the stopping/terminating condition for not performing a subsequent division by the base amount in the next lower unit.

Operation Result
T 52,000,000 / 1,000,000,000,000 FAIL
B 52,000,000 / 1,000,000,000 FAIL
M 52,000,000 / 1,000,000 PASS

Server-side Implementation In PHP

class Formatter
{

    const THOUSAND  = 'K';
    const MILLION   = 'M';
    const BILLION   = 'B';
    const TRILLION  = 'T';

    public static function humanReadable(
        $amount, 
        $decimalPlaces = 2, 
        $preserveAmountUpToUnit = ''
    )
    {
        $units = [
            self::TRILLION  => 1000 * 1000 * 1000 * 1000,
            self::BILLION   => 1000 * 1000 * 1000,
            self::MILLION   => 1000 * 1000,
            self::THOUSAND  => 1000,
        ];

        $result = $amount;
        $selectedUnit = '';
        foreach ($units as $key => $unit) {
            $result = $amount / $unit;
            if ($result >= 1) {
                $selectedUnit = $key;
                break;
            }
        }

        if ($selectedUnit && $preserveAmountUpToUnit && 
            $units[$selectedUnit] <= $units[$preserveAmountUpToUnit]
            ) { 
            return number_format($amount, $decimalPlaces);
        }

        return $selectedUnit ? 
                number_format($result, $decimalPlaces) . $selectedUnit : 
                $amount;
    }

}

What is the preserveAmountsUpToUnit parameter for?

Well, it was for my particular use case where I wanted amounts up to a certain unit to remain in their raw form instead of being shortened. You can see that in the second example under the usage section of this post. 
In the event you do not have such a use case, simply do not provide an argument for the last parameter during the function call.

Is 1000 * 1000 * 1000 * 1000 really necessary?

The thousands multiplier was to make certain that the appropriate number of zeros are in place and to make the code more readable, but that can conveniently be replaced with the exact amount, such as 1000000000 for a billion, if you prefer. 
This would not have been necessary in languages that allow the use of underscores in numeric literals, e.g., 1_000_000_000_000. Java have had this feature since Java SE 7, now Python in its version 3.6 (PEP 515) release, it only seems like a matter of time before it hits your programming language.

Client-side Implementation in JavaScript

The implementation can be viewed by clicking on Formatter JS. 
This version comes in handy if you are getting the data on the client-side, say through an API call in the browser, or using JavaScript on the server-side in NodeJS.

Formatter = {}
Formatter.THOUSAND = 'K';
Formatter.MILLION  = 'M';
Formatter.BILLION  = 'B';
Formatter.TRILLION = 'T';

Formatter.humanReadable = function(amount, dp=2, 
                                    preserveAmountUpToUnit = '') {
  var baseAmounts = {},
      result = amount,
      selectedUnit = '';
  
  if (isNaN(amount)) return amount;
  baseAmounts[this.TRILLION] = 1000 * 1000 * 1000 * 1000;
  baseAmounts[this.BILLION]  = 1000 * 1000 * 1000;
  baseAmounts[this.MILLION]  = 1000 * 1000;
  baseAmounts[this.THOUSAND] = 1000;
  
  
  for(var unit in baseAmounts) {
    var baseAmount = baseAmounts[unit];
    result = amount / baseAmount;
    if (result >= 1) {
      selectedUnit = unit;
      break;
    }
  }
  
  if (preserveAmountUpToUnit && selectedUnit && 
      baseAmounts[selectedUnit] <= baseAmounts[preserveAmountUpToUnit]) {
    return amount.toFixed(dp);  
  } 

  return result.toFixed(dp) + selectedUnit;
}

The Usage

Example Result
Formatter::humanReadable(1200) 1.20K
Formatter::humanReadable(1200, 2, Formatter::THOUSAND) 1,200.00
Formatter::humanReadable(123,440,782,000) 123.44B

Invocation in JavaScript would be something like the code below, note the only difference is the replace of the double colon (::), which is a scope resolution operator in PHP for accessing static and constant members of a class, with a single dot (.).

Formatter.humanReadable(1245000, 2, Formatter.THOUSAND)

Conclusion

With what we have now, we can confidently make any huge amount humanly readable to our application users when it becomes necessary. Do take note that my threshold is in trillions, but you could as well go beyond that if you deal with figures beyond that with some minimal additional lines of code being added.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.