Skip to content

Instantly share code, notes, and snippets.

@cslarsen
Created February 20, 2012 18:44
Show Gist options
  • Save cslarsen/1870641 to your computer and use it in GitHub Desktop.
Save cslarsen/1870641 to your computer and use it in GitHub Desktop.
Convert big number to human readable format
/*
* A simple way to format numbers as human readable strings.
* E.g., 123456789 ==> 123 million
*
* Written by Christian Stigen Larsen
* http://csl.sublevel3.org
*
* Placed in the public domain by the author, 2012
*/
#include <stdio.h>
#include <math.h>
#include <string.h>
/*
* Short scale units
* http://en.wikipedia.org/wiki/Short_scale
*/
static const char* short_scale[] = {
"",
"thousand",
"million",
"billion",
"trillion",
"quadrillion",
"quintillion",
"sextillion",
"septillion"
};
/*
* Long scale units
* http://en.wikipedia.org/wiki/Short_scale
*/
static const char* long_scale[] = {
"",
"thousand",
"million",
"milliard",
"billion",
"billiard",
"trillion",
"trilliard",
"quadrillion"
};
/*
* Convert number to human readable string using
* the given naming system.
*/
const char* scale(double n, int decimals = 1, const char* units[] = short_scale)
{
/*
* Number of digits in n is given by
* 10^x = n ==> x = log(n)/log(10) = log_10(n).
*
* So 1000 would be 1 + floor(log_10(10^3)) = 4 digits.
*/
int digits = n==0? 0 : 1+floor(log10l(fabs(n)));
// determine base 10 exponential
int exp = digits <= 4? 0 : 3*((digits-1)/3);
// normalized number
double m = n / powl(10, exp);
// no decimals? then don't print any
if ( m - static_cast<long>(n) == 0 )
decimals = 0;
// don't print unit for exp<3
static char s[32];
static const char* fmt[] = {"%1.*lf %s", "%1.*lf"};
sprintf(s, fmt[exp<3], decimals, m, units[exp/3]);
return s;
}
/*
* Convert number to short scale representation
*/
const char* sscale(double n, int decimals = 1)
{
static char s[32];
strcpy(s, scale(n, decimals, short_scale));
return s;
}
/*
* Convert number to long scale representation
*/
const char* lscale(double n, int decimals = 1)
{
static char s[32];
strcpy(s, scale(n, decimals, long_scale));
return s;
}
void test(double n)
{
printf("%.lf in short scale is %s and %s in long scale\n", n, sscale(n), lscale(n));
}
int main()
{
long numbers[] = {
1000000000,
0,
1,
12,
123,
1234,
12345,
123456,
1234567,
12345678,
123456789,
1234567890,
12345678901,
123456789012,
1234567890123,
12345678901234,
123456789012345,
1234567890123456,
12345678901234567,
123456789012345677,
1234567890123456789
};
for ( size_t n=0; n<sizeof(numbers)/sizeof(long); ++n )
test(numbers[n]);
test(-1);
test((double)12345.6789);
test((double)123456789012345678910.223);
}
@cslarsen
Copy link
Author

Compiling and running the code produces the following output:

$ clang -W -Wall human-numbers.cpp -o human-numbers && ./human-numbers
1000000000 in short scale is 1.0 billion and 1.0 milliard in long scale
0 in short scale is 0 and 0 in long scale
1 in short scale is 1 and 1 in long scale
12 in short scale is 12 and 12 in long scale
123 in short scale is 123 and 123 in long scale
1234 in short scale is 1234 and 1234 in long scale
12345 in short scale is 12.3 thousand and 12.3 thousand in long scale
123456 in short scale is 123.5 thousand and 123.5 thousand in long scale
1234567 in short scale is 1.2 million and 1.2 million in long scale
12345678 in short scale is 12.3 million and 12.3 million in long scale
123456789 in short scale is 123.5 million and 123.5 million in long scale
1234567890 in short scale is 1.2 billion and 1.2 milliard in long scale
12345678901 in short scale is 12.3 billion and 12.3 milliard in long scale
123456789012 in short scale is 123.5 billion and 123.5 milliard in long scale
1234567890123 in short scale is 1.2 trillion and 1.2 billion in long scale
12345678901234 in short scale is 12.3 trillion and 12.3 billion in long scale
123456789012345 in short scale is 123.5 trillion and 123.5 billion in long scale
1234567890123456 in short scale is 1.2 quadrillion and 1.2 billiard in long scale
12345678901234568 in short scale is 12.3 quadrillion and 12.3 billiard in long scale
123456789012345680 in short scale is 123.5 quadrillion and 123.5 billiard in long scale
1234567890123456768 in short scale is 1.2 quintillion and 1.2 trillion in long scale
-1 in short scale is -1 and -1 in long scale
12346 in short scale is 12.3 thousand and 12.3 thousand in long scale
123456789012345683968 in short scale is 123.5 quintillion and 123.5 trillion in long scale

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment