13,865,442 members
Reference
alternative version

#### Stats

7.6K views
9 bookmarked
Posted 18 Aug 2015
Licenced CPOL

# Number to english text in C++11

, 18 Aug 2015
Convert integer numbers to english text representation

## Introduction

Convert numbers in the range `-2^31` to `2^31` into english text, such as "one hundred twenty three" for 123.

## Using the code

The funciton that does the conversion is `str_rep()`. I wrote two versions of the `num_to_english_words()` function: one simple (the first one I created), which has duplicate code structures and therefore would be tedious to extend to support 128 bit integers; and one without duplication, more generic but also a bit harder to understand, would be easily extended to cover 128 bit integers. Yes, the second version is of dubious practical value: who would ever need to write such large numbers in English words -- but it was fun to write :)

Copy one of the two versions into your utility source file, and call as desired as per examples in main().

Simple , less generic version:

```#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

string
num_to_english_words(int num)
{
static const vector<string> digits = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
static const vector<string> teens = { "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" };
static const vector<string> tens = { "skip", "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety" };

if (num < 0)
return "minus " + str_rep(-num);

if (num < 10)
return digits[num];

if (num < 20)
return teens[num - 10];

if (num < 100)
{
if (num % 10 == 0)
return tens[num/10];
else
return tens[num/10] + ' ' + digits[num % 10];
}

if (num < 1000)
{
if (num % 100 == 0)
return digits[num / 100] + " hundred";
else
return digits[num / 100] + " hundred " + num_to_english_words(num % 100);
}

static const int one_million = 1000000;
if (num < one_million)
{
const int thousands = int(num/1000);
if (num % 1000 == 0)
return str_rep(thousands) + " thousand";
else
return str_rep(thousands) + " thousand " + num_to_english_words(num % 1000);
}

static const int one_billion = 1000000000;
if (num < one_billion)
{
const int millions = int(num/one_million);
if (num % one_million == 0)
return str_rep(millions) + " million";
else
return str_rep(millions) + " million " + num_to_english_words(num % one_million);
}

const int billions = int(num/one_billion);
if (num % one_billion == 0)
return str_rep(billions) + " billion";
else
return str_rep(billions) + " billion " + num_to_english_words(num % one_billion);
}```

More generic, 64-bit capabie (but more complex) version:

```#include <vector>
#include <map>
#include <iostream>
#include <algorithm>
#include <string>

using namespace std;  // never use this in a header file

string
str_rep_0_to_999(int num)
{
static const vector<string> digits = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
static const vector<string> teens = { "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" };
static const vector<string> tens = { "skip", "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety" };

if (num < 10)
return digits[num];

if (num < 20)
return teens[num - 10];

if (num < 100)
{
if (num % 10 == 0)
return tens[num / 10];
else
return tens[num / 10] + ' ' + digits[num % 10];
}

if (num % 100 == 0)
return digits[num / 100] + " hundred";
else
return digits[num / 100] + " hundred " + str_rep_0_to_999(num % 100);
}

short count_segments(int64_t num)
{
int count_segs = 0;
while ((num /= 1000) != 0)
count_segs++;
return count_segs;
}

string
num_to_english_words(int64_t num, short num_segments = -1)
{
if (num < 0)
return "negative " + num_to_english_words(-num);

if (num < 1000)
return str_rep_0_to_999(short(num));

static const vector<string> segments = { "skip", "thousand", "million", "billion", "trillion", "quatrillion", "quintillion"};

if (num_segments < 0)
num_segments = count_segments(num);
assert(num_segments > 0);

const string factor_name = segments[num_segments];
const int64_t factor = pow(1000, num_segments);
const int groups = int(num / factor);
const string rep = str_rep_0_to_999(groups) + " " + factor_name;
if (num % factor == 0)
return rep;
else
return rep + " " + num_to_english_words(num % factor, num_segments - 1);
}```

An example main() that uses it:

```int main()
{
vector<int> v = {0, 1, 12, 20, 23, 34, 50, 99, 123, 199, 256, 300, 591, 999, 1000, 8765, 23456, 99999};
for (auto x: v)
cout << x << " " << str_rep(x) << endl;

vector<int> v2 = { 1000000, 5000000, 9876543, 999999999, 1000000000, 1234567890 };
for (auto x : v2)
cout << x << " " << str_rep(x) << endl;

vector<int> v3 = { -1, -12, -199, -1000, -99999, -5000000, -1234567890 };
for (auto x : v3)
cout << x << " " << str_rep(x) << endl;

const auto large = int64_t(1234567890) * 1234567890;
cout << large << " " << num_to_english_words(large) << endl;
}```

Output: when example run (same for both versions):

```0 zero
1 one
12 twelve
20 twenty
23 twenty three
34 thirty four
50 fifty
99 ninety nine
123 one hundred twenty three
199 one hundred ninety nine
256 two hundred fifty six
300 three hundred
591 five hundred ninety one
999 nine hundred ninety nine

1000 one thousand
8765 eight thousand seven hundred sixty five
23456 twenty three thousand four hundred fifty six
99999 ninety nine thousand nine hundred ninety nine

1000000 one million
5000000 five million
9876543 nine million eight hundred seventy six thousand five hundred forty three
999999999 nine hundred ninety nine million nine hundred ninety nine thousand nine hundred ninety nine

1000000000 one billion
1234567890 one billion two hundred thirty four million five hundred sixty seven thousand eight hundred ninety

-1 negative one
-12 negative twelve
-199 negative one hundred ninety nine
-1000 negative one thousand
-99999 negative ninety nine thousand nine hundred ninety nine
-5000000 negative five million
-1234567890 negative one billion two hundred thirty four million five hundred sixty seven thousand eight hundred ninety

1524157875019052100 one quintillion five hundred twenty four quatrillion one hun
dred fifty seven trillion eight hundred seventy five billion nineteen million fi
fty two thousand one hundred```

Points of Interest

This uses recursion in order to maximize re-use. Uses C++11 range for-loop and initialization list. The more generic version is sigificantly more difficult to understand: blocks converted to loops,

## History

• Aug 20, 2015: first version
• Aug 23, 2015: second version

## Share

No Biography provided

## You may also be interested in...

 First Prev Next
 VERY INTERESTING ARTICLE learner198821-Aug-15 7:19 learner1988 21-Aug-15 7:19
 Last Visit: 20-Feb-19 6:05     Last Update: 20-Feb-19 6:05 Refresh 1

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Web05 | 2.8.190214.1 | Last Updated 18 Aug 2015