All pastes #838015 Raw Edit

LC Num2Text v1.1

public cpp v1 · immutable
#838015 ·published 2007-12-30 01:30 UTC
rendered paste body
/*(C) 2007 Rafal Maj, LimCore.comUses LC Num2Text software by LimCore www.limcore.com (on free LL GGC license).--- Free license: LL GGC (Gift, Give Credit) version 1http://www.limcore.com/ll_ggc/1/ - simple license to promote & share codeGift "AS IS", use how you want, credit author while he wishes, include license.You are allowed to use this software (delivered "AS IS" - use at own risk!)in any way (including commercial use, closing source, creating derived work)if You always met this rules:Give credit, in any software (and in Your media describing that software, including WWW), where this (or derived) work is used, by showing in a visible way (in English and in main languages of derived work)text:  "Uses TITLE software by NAME URL (on free LL GGC license).",replacing TITLE,NAME,URL with project title, author name and his website url,and providing access to copy of this license and all credits given by author.But remove credits if author requests it in writing. Also, name of authorcan not be used to endorse/promote derived work without author's permission;Above rules are inheritable - they apply as well to users of any fork ormodification of this work - author of base/previous version (of this work) must be credited also.Happy using & coding---TITLE for this source is: Num2TextNAME  for this source is: LimCoreURL   for this source is: limcore.com---Credits* Rafal Maj - author* Kaedenn - noticed 99*999 bug; translations?* Greetings to irc.freenode.org*//*Version 1.1Should spell (in words) numbers up to +- 999.999.999that is up to nine hundred ninety-nine million nine hundred ninety-nine thousand nine hundred ninety-ninein * english* polish* add your language here =)and supports printing floats as euro (including eurocent).To support another language hack:  copy SpellEn() -> SpellXx() and hack away   SpellEuro() - just the euro printing	change Print_String_As_Euro() and Teset() to debug new language*/#include <iostream>#include <sstream>#include <map>#include <vector>#include <string>#include <iomanip>#include <cmath>#include <boost/assign/std/vector.hpp>#include <boost/assign/std/map.hpp>using std::string;using std::map;using std::vector;using namespace boost::assign;// =====================================================================template <typename T> std::string STR(const T &val) {	std::ostringstream str;	str<<val;	return str.str();}// =====================================================================/*http://en.wikipedia.org/wiki/Eurohttp://en.wikipedia.org/wiki/Cent_%28currency%29http://en.wikipedia.org/wiki/Names_of_numbers_in_English*/string SpellEn(long num) {	if (num<0) {		return "minus " + SpellEn(-num);	}	if (num<=19) {		vector<string> w;		w += "zero", "one", "two", "three", "four", "five", "six", "seven",	"eight", "nine", "ten"			, "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen";		return w.at(num);	}	if (num<=99) {		vector<string> w;		w += "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety";		long ten = (num/10);		long one = num%10;		return 			w.at(ten-2) 			+ ((one!=0) ? ("-"+SpellEn(one)) : (""));	}	if (num<=999) {		long hundred = num / 100;		long rest = num % 100;		return 			SpellEn(hundred) + " hundred" 			+ ((rest!=0) ? (" "+SpellEn(rest)) : (""));	}	if (num<=999999) { // hundreds of thousands		long thousand = num / 1000;		long rest = num % 1000;		return 			SpellEn(thousand) + " thousand" 			+ ((rest!=0) ? (" "+SpellEn(rest)) : (""));	}	if (num<=999999999) { // hundreds of millions		long million = num / 1000000;		long rest = num % 1000000;		return 			SpellEn(million) + " million"			+ ((rest!=0) ? (" "+SpellEn(rest)) : (""));	}	return "???";}// =====================================================================string SpellPl(long num) {	if (num<0) {		return "minus " + SpellPl(-num);	}	if (num<=19) {		vector<string> w;		w += "zero", "jeden", "dwa", "trzy", "cztery", "pięć", "sześć", "siedem",	"osiem", "dziewięć", "dziesięć"			, "jedenaście", "dwanaście", "trzynaście", "czternaście", "piętnaście", "szesnaście", "siedemnaście", "osiemnaście", "dziewiętnąscie";		return w.at(num);	}	if (num<=99) {		vector<string> w;		w += "dwadzieścia", "trzydzieści", "czterdzieści", "pięćdziesiąt", "sześćdziesiąt", "siedemdziesiąt", "osiemdziesiąt", "dziewięćdziesiąt";		long ten = (num/10);		long one = num%10;		return 			w.at(ten-2) 			+ ((one!=0) ? (" "+SpellPl(one)) : (""));	}	if (num<=999) {		long hundred = num / 100;		string hundredStr="???";		{			vector<string> w;			w += "???", "sto", "dwieście", "trzysta", "czterysta", "pięćset", "sześćset", "siedemset",	"osiemset", "dziewięćset";			hundredStr = w.at(hundred);		};		long rest = num % 100;		return 			hundredStr			+ ((rest!=0) ? (" "+SpellPl(rest)) : (""));	}	if (num<=999999) { // hundreds of thousands		long thousand = num / 1000;		string thousandStr="";		if (thousand==1) thousandStr = "tysiąc";		else if (thousand<=4) thousandStr = SpellPl(thousand) + " tysiące";		else thousandStr = SpellPl(thousand) + " tysięcy";		long rest = num % 1000;		return 			thousandStr			+ ((rest!=0) ? (" "+SpellPl(rest)) : (""));	}	if (num<=999999999) { // hundreds of millions		long million = num / 1000000;		string millionStr="";		if (million==1) millionStr = "milion";		else if (million<=4) millionStr = SpellPl(million) + " miliony";		else millionStr = SpellPl(million) + " milionów";		long rest = num % 1000000;		return 			millionStr			+ ((rest!=0) ? (" "+SpellPl(rest)) : (""));	}	return "???";}// =====================================================================void Test(long i) {	std::cout << std::setw(5) << i << " is " << SpellEn(i) << std::endl;	std::cout << std::setw(5) << i << " to " << SpellPl(i) << std::endl;}std::string SpellEuro(double num, const std::string & lang="en") {	double numAbs = std::fabs(num); // absolute, so the minus can be handled by hand before the numbers	long full = (long)numAbs;	long cent = (long)(0.1 + (numAbs - full) * 100); // the minus part will be handled by full	// (or will be added by hand, for -0.99 case where the "zero" is skipped) 	bool isZero = (full==0) && (cent==0); // 0.00 (after rouding if float num was strange)	bool isMinus = num < 0;//	std::cout << "\n[" << num << " -> " << numAbs <<  " gives e="<<full<<" c="<<cent<< "] \n";		std::string out;	if (lang=="0.00") {		out += (isMinus?"-":"") + STR(full) + ".";		if (cent<10) out += "0";		out += STR(cent);		out += "€";	}	else if (lang=="0 00") {		out += "€" + STR(isMinus?"-":"") + STR(full) + " " + STR(cent) + "¢";	}	else if (lang=="en") {		if (isMinus && !isZero) out += "minus "; // the !isZero shouldnt be needed probably but why not		if (full || isZero) out += SpellEn(full) + " euro"; 		if (cent!=0) { // cents			if (full) out += " and "; // there was some full-euro part before			out += SpellEn(cent) + " eurocent";		}	}	else if (lang=="pl") {		if (isMinus && !isZero) out += "minus "; // the !isZero shouldnt be needed probably but why not		if (full || isZero) out += SpellPl(full) + " euro";		if (cent!=0) { // cents			if (full) out += " i "; // there was some full-euro part before			// damn polish grammer:			//			//  rule1:  0.. 9 is: 1-grosz   2..4-grosze  5..9-groszy			//  rule2: 10..19 is: 11..19-groszy			//  rule3: 20..99 is: n0-groszy  n1-groszy  n2..n4-grosze  n5..n9-groszy  where n is 20,30,40..90			//  s/grosz/eurocent			//  s/grosze/eurocenty			//  s/groszy/eurocentów			//  sigh :)			out += SpellPl(cent) + " ";			if (cent<=9) { // rule1				if (cent==1) out+="eurocent"; // 1				else if (cent<=4) out+="eurocenty"; // 2 3 4				else out+="eurocentów"; // 8			}			else if (cent<=19) { // rule 2				out+="eurocentów"; // 12			}			else { // rule3				long d = cent % 10;				if (d==0) out += "eurocentów"; // 20 30 40				else if (d==1) out += "eurocentów"; // 21 31 91				else if (d<=4) out += "eurocenty"; // 22 23 24 54 75				else out += "eurocentów"; // 25 55 75 99			}		}	}	return out;}void Print_String_As_Euro(std::string str) {	using std::cout; using std::endl;			double num=0;	std::istringstream istr(str);	istr>>num;				cout << SpellEuro(num,"0.00") << "   ";	cout << SpellEuro(num,"0 00") << endl;	cout << SpellEuro(num,"en") << "   ";	cout << SpellEuro(num,"pl") << endl;	cout << endl;}// =====================================================================// =====================================================================// =====================================================================void TestCase() {	Test(-1);	Test(0);	Test(15);	Test(1234);	Test(18001);	Test(3019);	Test(-17934);	Print_String_As_Euro("19352.94");	Print_String_As_Euro("2105.02");	Print_String_As_Euro("1444.01");	Print_String_As_Euro("99050");	Print_String_As_Euro("1.00");	Print_String_As_Euro("1.01");	Print_String_As_Euro("1.02");	Print_String_As_Euro("1.04");	Print_String_As_Euro("1.09");	Print_String_As_Euro("1.81");	Print_String_As_Euro("1.85");	Print_String_As_Euro("-0.99");	Print_String_As_Euro("-2.01");	Test(100);	Test(10100);	Test(1*100*1000);	Test(2*100*1000);	Test(9*100*1000);	Test(9*100*1000 + 5003);	Test(1000*1000);	Test(2000*1000);	Test(2000*1000 + 5007);	Test(999111999); // 999 millions	Print_String_As_Euro("-912000042.11"); // finall test \o/ 	Print_String_As_Euro("0");	Print_String_As_Euro("1");	Print_String_As_Euro("0.42");	Print_String_As_Euro("1.42");	Print_String_As_Euro("-0"); // yeah it doesnt make much sense, but just to test will it work like "0"	Print_String_As_Euro("-1"); 	Print_String_As_Euro("-0.42");	Print_String_As_Euro("-1.42");}void TestCaseFull() {	// some test cases	for (long i=-5; i<25; ++i) Test(i);	for (long i=20; i<100; i+=10) {		Test(i);		Test(i+1);		Test(i+9);	}	for (long i=100; i<1000; i+=100) {		Test(i);		Test(i+1);		Test(i+11);		Test(i+43);	}	for (long i=1000; i<20*1000; i+=1000) {		Test(i);		Test(i+1);		Test(i+11);		Test(i+43);		Test(i+234);		Test(i+354);		Test(i+454);		Test(i+654);		Test(i+999);	}	TestCase();}void ExecuteCommand(std::string command) {	// command can be:	// t - run test case	// T - run full test case	// 123.45 - a long number - spell it as Euro		if (command=="T") TestCaseFull();	else if (command=="t") TestCase();	else Print_String_As_Euro(command);}int main(int argc, const char** argv) {	using std::cout; using std::endl;	std::string command;	if (argc>=2) command = argv[1];	else {		cout << "What to do?\n"			"  t      - run testcase\n"			"  T      - run full testcase\n"			"  123.45 - or other number - spell it as euro value\n"			"\nWrite and press ENTER\n";		std::cin >> command;	}	ExecuteCommand(command);}