Convert number to literal string

Here is a little function that translates numbers like 123 into literal strings like “one hundred twenty three”, the result is in English only:

#include <string>
#include <map>
#include <stack>
#include <iostream>
#include <stdint.h>
using namespace std;

string num2str(uint64_t num) {
	using mapping_t = map<uint64_t, string>;
	static mapping_t mapping = { {0, "zero"},{1, "one"}, {2, "two"}, {3, "three"},{4, "four"},
								 {5, "five"},{6, "six"},{7, "seven"},{8, "eight"},{9, "nine"},
								 {10, "ten"}, {11, "eleven"}, {12, "twelve"}, {13, "thirteen"},
								 {14, "fourteen"}, {15, "fifteen"}, {16, "sixteen"}, {17, "seventeen"},
								 {18, "eighteen"}, {19, "nineteen"}, {20, "twenty"}, {30, "thirty"},
								 {40, "fourty"}, {50, "fifty"}, {60, "sixty"}, {70, "seventy"},
								 {80, "eighty"}, {90, "ninety"}, {100, "hundred"}, {1000, "thousand"},
								 {1000000, "million"}, {1000000000, "billion"}, { 1000000000000, "trillion"} };
	string str;
	if (num == 0) {
		str = mapping[0];
	}
	else {
		enum DATA_FLAGS {
			FLAG_REMAINING = 1,
			FLAG_UNIT
		};
		using stack_t = stack<uint64_t>;
		stack_t s;
		s.push(num);
		s.push(FLAG_REMAINING);
		while (!s.empty()) {
			uint64_t flag = s.top();
			s.pop();
			uint64_t data = s.top();
			s.pop();

			if (flag == FLAG_UNIT) {
				str += " ";
				str += mapping[data];
			} else {
				if (data <= 20) {
					if (!str.empty())
						str += " ";
					str += mapping[data];
				} else if (data < 100) {
					uint64_t tens = (data / 10) * 10;
					uint64_t digits = data % 10;
					if (!str.empty())
						str += " ";
					str += mapping[tens];
					if (digits > 0) {
						if (!str.empty())
							str += "-";
						str += mapping[digits];
					}
				}
				else {
					for (mapping_t::reverse_iterator it_last = mapping.rbegin(); it_last != mapping.rend(); ++it_last) {
						uint64_t base = it_last->first;
						if (data >= base) {
							uint64_t units = data / base;
							uint64_t remaining = data % base;
							s.push(remaining);
							s.push(FLAG_REMAINING);
							s.push(base);
							s.push(FLAG_UNIT);
							s.push(units);
							s.push(FLAG_REMAINING);
							break;
						}
					}
				}
			}
		}
	}

	return str;
}

Test code with a large number:

int main() {
	string str = num2str(1234567890123);
	cout << str.c_str() << endl;
    return 0;
}

Output:

one trillion two hundred thirty-four billion five hundred sixty-seven million eight hundred ninety thousand one hundred twenty-three
Advertisements

Posted on October 31, 2016, in Uncategorized. Bookmark the permalink. Leave a comment.

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s

%d bloggers like this: